Best Python code snippet using pyatom_python
parser.py
Source:parser.py  
...56        else:57            self._configs = configs58    def _getBooleanAttribute(self, node, name):59        """If node has no attribute named |name| return True."""60        v = self._getAttribute(node, name)61        if not v:62            return True63        v = v.lower()64        r = v in ('true', 'yes', '1')65        if not r:66            assert v in ('false', 'no', '0')67        return r68    def substituteConfigVariables(self, xmlString, final=False):69        result = []70        pos = 071        numVarsLeft = 072        numVarsFound = 073        unresolved = []74        if not final:75            logging.info("Analyzing XML for potential macros.")76        for m in re.finditer(r"\$(\w+:?\w*)\$", xmlString):77            result.append(xmlString[pos:m.start(0)])78            varName = m.group(1)79            handled = False80            if varName in self._configs:81                logging.debug('Setting "{}" to "{}"'.format(varName, self._configs[varName]))82                result.append(self._configs[varName])83                handled = True84            elif ':' in varName:85                # Instance provider86                (instanceProviderName, identifier) = varName.split(':')87                instanceProvider = getInstanceProvider(instanceProviderName)88                try:89                    instance = str(instanceProvider.getInstanceById(identifier, self._configs))90                    logging.debug('Setting "{}" to "{}"'.format(varName, instance))91                    result.append(instance)92                    handled = True93                except Exception:94                    # allow it to fail for now, probably need other macros to resolve this95                    pass96            if not handled:97                result.append(m.group(0))98                unresolved.append(m.group(1))99                numVarsLeft += 1100            pos = m.end(0)101            numVarsFound += 1102        result.append(xmlString[pos:])103        if not final:104            logging.info("Found {} macros, {} resolved.".format(numVarsFound, numVarsFound - numVarsLeft))105        elif unresolved:106            for u in unresolved:107                logging.warning("Unresolved macro: %s" % u)108        return "".join(result)109    def parse(self, uri):110        """111        Parse a Peach XML file pointed to by uri.112        """113        logging.info(highlight.info("Parsing %s" % uri))114        doc = etree.parse(uri, parser=self._parser, base_url="http://phed.org").getroot()115        if "_target" in self._configs:116            target = etree.parse(self._configs["_target"], parser=self._parser, base_url="http://phed.org").getroot()117            if split_ns(target.tag)[1] != 'Peach':118                raise PeachException("First element in document must be Peach, not '%s'" % target.tag)119            for child in target.iterchildren():120                doc.append(child)121            del self._configs["_target"]122        # try early to find configuration macros123        self.FindConfigurations(doc)124        xmlString = etree.tostring(doc)125        return self.parseString(xmlString, findConfigs=False)126    def parseString(self, xml, findConfigs=True):127        """128        Parse a string as Peach XML.129        """130        xml = self.substituteConfigVariables(xml)131        doc = etree.fromstring(xml, parser=self._parser, base_url="http://phed.org")132        return self.HandleDocument(doc, findConfigs=findConfigs)133    def GetClassesInModule(self, module):134        """135        Return array of class names in module136        """137        classes = []138        for item in dir(module):139            i = getattr(module, item)140            if type(i) == type and item[0] != '_':141                classes.append(item)142            elif type(i) == types.MethodType and item[0] != '_':143                classes.append(item)144            elif type(i) == types.FunctionType and item[0] != '_':145                classes.append(item)146            elif repr(i).startswith("<class"):147                classes.append(item)148        return classes149    def FindConfigurations(self, doc):150        # FIRST check for a configuration section. If one exists, we need to parse it and then restart.151        #print "Looking for Configuration element"152        has_config = False153        for child in doc.iterchildren():154            child_tag = split_ns(child.tag)[1]155            if child_tag != 'Configuration':156                continue157            #assert not has_config, "Multiple <Configuration> elements"158            has_config = True159            #print "Found Configuration element"160            for child in child.iterchildren():161                child_tag = split_ns(child.tag)[1]162                assert child_tag == "Macro", "Unknown child in Configuration element: {}".format(child_tag)163                name = child.get("name")164                if name not in self._configs:165                    #print "\t%s = %s" % (name, child.get("value"))166                    self._configs[name] = child.get("value")167                else:168                    #print "\t%s = %s [dropped]" % (name, child.get("value"))169                    pass170        return has_config171    def HandleDocument(self, doc, uri="", findConfigs=True):172        if findConfigs and self.FindConfigurations(doc):173            return self.parseString(etree.tostring(doc), findConfigs=False)174        #self.StripComments(doc)175        self.StripText(doc)176        ePeach = doc177        if split_ns(ePeach.tag)[1] != 'Peach':178            raise PeachException("First element in document must be Peach, not '%s'" % ePeach.tag)179        peach = dom.Peach()180        peach.peachPitUri = uri181        #peach.node = doc182        self.context = peach183        peach.mutators = None184        #: List of nodes that need some parse love list of [xmlNode, parent]185        self.unfinishedReferences = []186        for i in ['templates', 'data', 'agents', 'namespaces', 'tests', 'runs']:187            setattr(peach, i, ElementWithChildren())188        # Peach attributes189        for i in ['version', 'author', 'description']:190            setattr(peach, i, self._getAttribute(ePeach, i))191        # The good stuff -- We are going todo multiple passes here to increase the likely hood192        # that things will turn out okay.193        # Pass 1 -- Include, PythonPath, Defaults194        for child in ePeach.iterchildren():195            child_tag = split_ns(child.tag)[1]196            if child_tag == 'Include':197                # Include this file198                nsName = self._getAttribute(child, 'ns')199                nsSrc = self._getAttribute(child, 'src')200                parser = ParseTemplate(self._configs)201                ns = parser.parse(nsSrc)202                ns.name = nsName + ':' + nsSrc203                ns.nsName = nsName204                ns.nsSrc = nsSrc205                ns.elementType = 'namespace'206                ns.toXml = new_instancemethod(dom.Namespace.toXml, ns)207                nss = Namespace()208                nss.ns = ns209                nss.nsName = nsName210                nss.nsSrc = nsSrc211                nss.name = nsName + ":" + nsSrc212                nss.parent = peach213                ns.parent = nss214                peach.append(nss)215                peach.namespaces.append(ns)216                setattr(peach.namespaces, nsName, ns)217            elif child_tag == 'PythonPath':218                # Add a search path219                p = self.HandlePythonPath(child, peach)220                peach.append(p)221                sys.path.append(p.name)222            elif child_tag == 'Defaults':223                self.HandleDefaults(child, peach)224        # one last check for unresolved macros225        for child in ePeach.iterdescendants():226            for k,v in list(child.items()):227                child.set(k, self.substituteConfigVariables(v, final=True))228        # Pass 2 -- Import229        for child in ePeach.iterchildren():230            child_tag = split_ns(child.tag)[1]231            if child_tag == 'Import':232                # Import module233                if child.get('import') is None:234                    raise PeachException("Import element did not have import attribute!")235                importStr = self._getAttribute(child, 'import')236                if child.get('from') is not None:237                    fromStr = self._getAttribute(child, 'from')238                    if importStr == "*":239                        module = __import__(PeachStr(fromStr), globals(), locals(), [PeachStr(importStr)], -1)240                        try:241                            # If we are a module with other modules in us then we have an __all__242                            for item in module.__all__:243                                globals()["PeachXml_" + item] = getattr(module, item)244                        except:245                            # Else we just have some classes in us with no __all__246                            for item in self.GetClassesInModule(module):247                                globals()["PeachXml_" + item] = getattr(module, item)248                    else:249                        module = __import__(PeachStr(fromStr), globals(), locals(), [PeachStr(importStr)], -1)250                        for item in importStr.split(','):251                            item = item.strip()252                            globals()["PeachXml_" + item] = getattr(module, item)253                else:254                    globals()["PeachXml_" + importStr] = __import__(PeachStr(importStr), globals(), locals(), [], -1)255                Holder.globals = globals()256                Holder.locals = locals()257                i = Element()258                i.elementType = 'import'259                i.importStr = self._getAttribute(child, 'import')260                i.fromStr = self._getAttribute(child, 'from')261                peach.append(i)262        # Pass 3 -- Template263        for child in ePeach.iterchildren():264            child_tag = split_ns(child.tag)[1]265            if child_tag == "Python":266                code = self._getAttribute(child, "code")267                if code is not None:268                    exec(code)269            elif child_tag == 'Analyzer':270                self.HandleAnalyzerTopLevel(child, peach)271            elif child_tag == 'DataModel' or child_tag == 'Template':272                # do something273                template = self.HandleTemplate(child, peach)274                #template.node = child275                peach.append(template)276                peach.templates.append(template)277                setattr(peach.templates, template.name, template)278        # Pass 4 -- Data, Agent279        for child in ePeach.iterchildren():280            child_tag = split_ns(child.tag)[1]281            if child_tag == 'Data':282                # do data283                data = self.HandleData(child, peach)284                #data.node = child285                peach.append(data)286                peach.data.append(data)287                setattr(peach.data, data.name, data)288            elif child_tag == 'Agent':289                agent = self.HandleAgent(child, None)290                #agent.node = child291                peach.append(agent)292                peach.agents.append(agent)293                setattr(peach.agents, agent.name, agent)294            elif child_tag == 'StateModel' or child_tag == 'StateMachine':295                stateMachine = self.HandleStateMachine(child, peach)296                #stateMachine.node = child297                peach.append(stateMachine)298            elif child_tag == 'Mutators':299                if self._getBooleanAttribute(child, "enabled"):300                    mutators = self.HandleMutators(child, peach)301                    peach.mutators = mutators302        # Pass 5 -- Tests303        for child in ePeach.iterchildren():304            child_tag = split_ns(child.tag)[1]305            if child_tag == 'Test':306                tests = self.HandleTest(child, None)307                #tests.node = child308                peach.append(tests)309                peach.tests.append(tests)310                setattr(peach.tests, tests.name, tests)311            elif child_tag == 'Run':312                run = self.HandleRun(child, None)313                #run.node = child314                peach.append(run)315                peach.runs.append(run)316                setattr(peach.runs, run.name, run)317        # Pass 6 -- Analyzers318        # Simce analyzers can modify the DOM we need to make our list319        # of objects we will look at first!320        objs = []321        for child in peach.getElementsByType(Blob):322            if child.analyzer is not None and child.defaultValue is not None and child not in objs:323                objs.append(child)324        for child in peach.getElementsByType(String):325            if child.analyzer is not None and child.defaultValue is not None and child not in objs:326                objs.append(child)327        for child in objs:328            try:329                analyzer = eval("%s()" % child.analyzer)330            except:331                analyzer = eval("PeachXml_" + "%s()" % child.analyzer)332            analyzer.asDataElement(child, {}, child.defaultValue)333        # We suck, so fix this up334        peach._FixParents()335        peach.verifyDomMap()336        #peach.printDomMap()337        return peach338    def StripComments(self, node):339        i = 0340        while i < len(node):341            if not etree.iselement(node[i]):342                del node[i] # may not preserve text, don't care343            else:344                self.StripComments(node[i])345                i += 1346    def StripText(self, node):347        node.text = node.tail = None348        for desc in node.iterdescendants():349            desc.text = desc.tail = None350    def GetRef(self, str, parent=None, childAttr='templates'):351        """352        Get the object indicated by ref.  Currently the object must have353        been defined prior to this point in the XML354        """355        #print "GetRef(%s) -- Starting" % str356        origStr = str357        baseObj = self.context358        hasNamespace = False359        isTopName = True360        found = False361        # Parse out a namespace362        if str.find(":") > -1:363            ns, tmp = str.split(':')364            str = tmp365            #print "GetRef(%s): Found namepsace: %s" % (str, ns)366            # Check for namespace367            if hasattr(self.context.namespaces, ns):368                baseObj = getattr(self.context.namespaces, ns)369            else:370                #print self371                raise PeachException("Unable to locate namespace: " + origStr)372            hasNamespace = True373        for name in str.split('.'):374            #print "GetRef(%s): Looking for part %s" % (str, name)375            found = False376            if not hasNamespace and isTopName and parent is not None:377                # check parent, walk up from current parent to top378                # level parent checking at each level.379                while parent is not None and not found:380                    #print "GetRef(%s): Parent.name: %s" % (name, parent.name)381                    if hasattr(parent, 'name') and parent.name == name:382                        baseObj = parent383                        found = True384                    elif hasattr(parent, name):385                        baseObj = getattr(parent, name)386                        found = True387                    elif hasattr(parent.children, name):388                        baseObj = getattr(parent.children, name)389                        found = True390                    elif hasattr(parent, childAttr) and hasattr(getattr(parent, childAttr), name):391                        baseObj = getattr(getattr(parent, childAttr), name)392                        found = True393                    else:394                        parent = parent.parent395            # check base obj396            elif hasattr(baseObj, name):397                baseObj = getattr(baseObj, name)398                found = True399            # check childAttr400            elif hasattr(baseObj, childAttr):401                obj = getattr(baseObj, childAttr)402                if hasattr(obj, name):403                    baseObj = getattr(obj, name)404                    found = True405            else:406                raise PeachException("Could not resolve ref %s" % origStr)407            # check childAttr408            if found == False and hasattr(baseObj, childAttr):409                obj = getattr(baseObj, childAttr)410                if hasattr(obj, name):411                    baseObj = getattr(obj, name)412                    found = True413            # check across namespaces if we can't find it in ours414            if isTopName and found == False:415                for child in baseObj:416                    if child.elementType != 'namespace':417                        continue418                    #print "GetRef(%s): CHecking namepsace: %s" % (str, child.name)419                    ret = self._SearchNamespaces(child, name, childAttr)420                    if ret:421                        #print "GetRef(%s) Found part %s in namespace" % (str, name)422                        baseObj = ret423                        found = True424            isTopName = False425        if not found:426            raise PeachException("Unable to resolve reference: %s" % origStr)427        return baseObj428    def _SearchNamespaces(self, obj, name, attr):429        """430        Used by GetRef to search across namespaces431        """432        #print "_SearchNamespaces(%s, %s)" % (obj.name, name)433        #print "dir(obj): ", dir(obj)434        # Namespaces are stuffed under this variable435        # if we have it we should be it :)436        if hasattr(obj, 'ns'):437            obj = obj.ns438        if hasattr(obj, name):439            return getattr(obj, name)440        elif hasattr(obj, attr) and hasattr(getattr(obj, attr), name):441            return getattr(getattr(obj, attr), name)442        for child in obj:443            if child.elementType != 'namespace':444                continue445            ret = self._SearchNamespaces(child, name, attr)446            if ret is not None:447                return ret448        return None449    def GetDataRef(self, str):450        """451        Get the data object indicated by ref.  Currently the object must452        have been defined prior to this point in the XML.453        """454        origStr = str455        baseObj = self.context456        # Parse out a namespace457        if str.find(":") > -1:458            ns, tmp = str.split(':')459            str = tmp460            #print "GetRef(): Found namepsace:",ns461            # Check for namespace462            if hasattr(self.context.namespaces, ns):463                baseObj = getattr(self.context.namespaces, ns)464            else:465                raise PeachException("Unable to locate namespace")466        for name in str.split('.'):467            # check base obj468            if hasattr(baseObj, name):469                baseObj = getattr(baseObj, name)470            # check templates471            elif hasattr(baseObj, 'data') and hasattr(baseObj.data, name):472                baseObj = getattr(baseObj.data, name)473            else:474                raise PeachException("Could not resolve ref '%s'" % origStr)475        return baseObj476    _regsHex = (477        re.compile(r"^([,\s]*\\x([a-zA-Z0-9]{2})[,\s]*)"),478        re.compile(r"^([,\s]*%([a-zA-Z0-9]{2})[,\s]*)"),479        re.compile(r"^([,\s]*0x([a-zA-Z0-9]{2})[,\s]*)"),480        re.compile(r"^([,\s]*x([a-zA-Z0-9]{2})[,\s]*)"),481        re.compile(r"^([,\s]*([a-zA-Z0-9]{2})[,\s]*)")482    )483    def GetValueFromNode(self, node):484        value = None485        type = 'string'486        if node.get('valueType') is not None:487            type = self._getAttribute(node, 'valueType')488            if not (type == 'literal' or type == 'hex'):489                type = 'string'490        if node.get('value') is not None:491            value = self._getAttribute(node, 'value')492            # Convert variouse forms of hex into a binary string493            if type == 'hex':494                if len(value) == 1:495                    value = "0" + value496                ret = ''497                valueLen = len(value) + 1498                while valueLen > len(value):499                    valueLen = len(value)500                    for i in range(len(self._regsHex)):501                        match = self._regsHex[i].search(value)502                        if match is not None:503                            while match is not None:504                                ret += chr(int(match.group(2), 16))505                                value = self._regsHex[i].sub('', value)506                                match = self._regsHex[i].search(value)507                            break508                return ret509            elif type == 'literal':510                return eval(value)511        if value is not None and (type == 'string' or node.get('valueType') is None):512            value = re.sub(r"([^\\])\\n", r"\1\n", value)513            value = re.sub(r"([^\\])\\r", r"\1\r", value)514            value = re.sub(r"([^\\])\\t", r"\1\t", value)515            value = re.sub(r"([^\\])\\n", r"\1\n", value)516            value = re.sub(r"([^\\])\\r", r"\1\r", value)517            value = re.sub(r"([^\\])\\t", r"\1\t", value)518            value = re.sub(r"^\\n", r"\n", value)519            value = re.sub(r"^\\r", r"\r", value)520            value = re.sub(r"^\\t", r"\t", value)521            value = re.sub(r"\\\\", r"\\", value)522        return value523    def GetValueFromNodeString(self, node):524        """525        This one is specific to <String> elements.  We526        want to preserve unicode characters.527        """528        value = None529        type = 'string'530        if node.get('valueType') is not None:531            type = self._getAttribute(node, 'valueType')532            if not type in ['literal', 'hex', 'string']:533                raise PeachException("Error: [%s] has invalid valueType attribute." % node.getFullname())534        if node.get('value') is not None:535            value = node.get('value')536            # Convert variouse forms of hex into a binary string537            if type == 'hex':538                value = str(value)539                if len(value) == 1:540                    value = "0" + value541                ret = ''542                valueLen = len(value) + 1543                while valueLen > len(value):544                    valueLen = len(value)545                    for i in range(len(self._regsHex)):546                        match = self._regsHex[i].search(value)547                        if match is not None:548                            while match is not None:549                                ret += chr(int(match.group(2), 16))550                                value = self._regsHex[i].sub('', value)551                                match = self._regsHex[i].search(value)552                            break553                return ret554            elif type == 'literal':555                value = eval(value)556        if value is not None and type == 'string':557            value = re.sub(r"([^\\])\\n", r"\1\n", value)558            value = re.sub(r"([^\\])\\r", r"\1\r", value)559            value = re.sub(r"([^\\])\\t", r"\1\t", value)560            value = re.sub(r"([^\\])\\n", r"\1\n", value)561            value = re.sub(r"([^\\])\\r", r"\1\r", value)562            value = re.sub(r"([^\\])\\t", r"\1\t", value)563            value = re.sub(r"^\\n", r"\n", value)564            value = re.sub(r"^\\r", r"\r", value)565            value = re.sub(r"^\\t", r"\t", value)566            value = re.sub(r"\\\\", r"\\", value)567        return value568    def GetValueFromNodeNumber(self, node):569        value = None570        type = 'string'571        if node.get('valueType') is not None:572            type = self._getAttribute(node, 'valueType')573            if not type in ['literal', 'hex', 'string']:574                raise PeachException("Error: [%s] has invalid valueType attribute." % node.getFullname())575        if node.get('value') is not None:576            value = self._getAttribute(node, 'value')577            # Convert variouse forms of hex into a binary string578            if type == 'hex':579                if len(value) == 1:580                    value = "0" + value581                ret = ''582                valueLen = len(value) + 1583                while valueLen > len(value):584                    valueLen = len(value)585                    for i in range(len(self._regsHex)):586                        match = self._regsHex[i].search(value)587                        if match is not None:588                            while match is not None:589                                ret += match.group(2)590                                value = self._regsHex[i].sub('', value)591                                match = self._regsHex[i].search(value)592                            break593                return int(ret, 16)594            elif type == 'literal':595                value = eval(value)596        return value597    # Handlers for Template ###################################################598    def HandleTemplate(self, node, parent):599        """600        Parse an element named Template.  Can handle actual601        Template elements and also reference Template elements.602        e.g.:603        <Template name="Xyz"> ... </Template>604        or605        <Template ref="Xyz" />606        """607        template = None608        # ref609        if node.get('ref') is not None:610            # We have a base template611            obj = self.GetRef(self._getAttribute(node, 'ref'))612            template = obj.copy(parent)613            template.ref = self._getAttribute(node, 'ref')614            template.parent = parent615        else:616            template = Template(self._getAttribute(node, 'name'))617            template.ref = None618            template.parent = parent619        # name620        if node.get('name') is not None:621            template.name = self._getAttribute(node, 'name')622        template.elementType = 'template'623        # mutable624        mutable = self._getAttribute(node, 'mutable')625        if mutable is None or len(mutable) == 0:626            template.isMutable = True627        elif mutable.lower() == 'true':628            template.isMutable = True629        elif mutable.lower() == 'false':630            template.isMutable = False631        else:632            raise PeachException(633                "Attribute 'mutable' has unexpected value [%s], only 'true' and 'false' are supported." % mutable)634        # pointer635        pointer = self._getAttribute(node, 'pointer')636        if pointer is None:637            pass638        elif pointer.lower() == 'true':639            template.isPointer = True640        elif pointer.lower() == 'false':641            template.isPointer = False642        else:643            raise PeachException(644                "Attribute 'pointer' has unexpected value [%s], only 'true' and 'false' are supported." % pointer)645        # pointerDepth646        if node.get("pointerDepth") is not None:647            template.pointerDepth = self._getAttribute(node, 'pointerDepth')648        # children649        self.HandleDataContainerChildren(node, template)650        # Switch any references to old name651        if node.get('ref') is not None:652            oldName = self._getAttribute(node, 'ref')653            for relation in template._genRelationsInDataModelFromHere():654                if relation.of == oldName:655                    relation.of = template.name656                elif relation.From == oldName:657                    relation.From = template.name658        #template.printDomMap()659        return template660    def HandleCommonTemplate(self, node, elem):661        """662        Handle the common children of data elements like String and Number.663        """664        elem.onArrayNext = self._getAttribute(node, "onArrayNext")665        for child in node:666            child_nodeName = split_ns(child.tag)[1]667            if child_nodeName == 'Relation':668                relation = self.HandleRelation(child, elem)669                elem.relations.append(relation)670            elif child_nodeName == 'Transformer':671                if elem.transformer is not None:672                    raise PeachException("Error, data element [%s] already has a transformer." % elem.name)673                elem.transformer = self.HandleTransformer(child, elem)674            elif child_nodeName == 'Fixup':675                self.HandleFixup(child, elem)676            elif child_nodeName == 'Placement':677                self.HandlePlacement(child, elem)678            elif child_nodeName == 'Hint':679                self.HandleHint(child, elem)680            else:681                raise PeachException("Found unexpected child node '%s' in element '%s'." % (child_nodeName, elem.name))682    def HandleTransformer(self, node, parent):683        """684        Handle Transformer element685        """686        transformer = Transformer(parent)687        childTransformer = None688        params = []689        # class690        if node.get("class") is None:691            raise PeachException("Transformer element missing class attribute")692        generatorClass = self._getAttribute(node, "class")693        transformer.classStr = generatorClass694        # children695        for child in node.iterchildren():696            child_nodeName = split_ns(child.tag)[1]697            if child_nodeName == 'Transformer':698                if childTransformer is not None:699                    raise PeachException("A transformer can only have one child transformer")700                childTransformer = self.HandleTransformer(child, transformer)701                continue702            if child_nodeName == 'Param':703                param = self.HandleParam(child, transformer)704                transformer.append(param)705                params.append([param.name, param.defaultValue])706        code = "PeachXml_" + generatorClass + '('707        isFirst = True708        for param in params:709            if not isFirst:710                code += ', '711            else:712                isFirst = False713            code += PeachStr(param[1])714        code += ')'715        trans = eval(code, globals(), locals())716        if childTransformer is not None:717            trans.addTransformer(childTransformer.transformer)718        transformer.transformer = trans719        if parent is not None:720            parent.transformer = transformer721            transformer.parent = parent722            #parent.append(transformer)723        return transformer724    def HandleDefaults(self, node, parent):725        """726        Handle data element defaults727        """728        # children729        for child in node.iterchildren():730            child_nodeName = split_ns(child.tag)[1]731            if child_nodeName == 'Blob':732                if child.get('valueType') is not None:733                    Blob.defaultValueType = self._getAttribute(child, 'valueType')734                    if Blob.defaultValueType not in ['string', 'literal', 'hex']:735                        raise PeachException("Error, default value for Blob.valueType incorrect.")736                if child.get('lengthType') is not None:737                    Blob.defaultLengthType = self._getAttribute(child, 'lengthType')738                    if Blob.defaultLengthType not in ['string', 'literal', 'calc']:739                        raise PeachException("Error, default value for Blob.lengthType incorrect.")740            elif child_nodeName == 'Flags':741                if child.get('endian') is not None:742                    Flags.defaultEndian = self._getAttribute(child, 'endian')743                    if Flags.defaultEndian not in ['little', 'big', 'network']:744                        raise PeachException("Error, default value for Flags.endian incorrect.")745            elif child_nodeName == 'Number':746                if child.get('endian') is not None:747                    Number.defaultEndian = self._getAttribute(child, 'endian')748                    if Number.defaultEndian not in ['little', 'big', 'network']:749                        raise PeachException("Error, default value for Number.endian incorrect.")750                if child.get('size') is not None:751                    Number.defaultSize = int(self._getAttribute(child, 'size'))752                    if Number.defaultSize not in Number._allowedSizes:753                        raise PeachException("Error, default value for Number.size incorrect.")754                if child.get('signed') is not None:755                    Number.defaultSigned = self._getAttribute(child, 'signed')756                    if Number.defaultSigned not in ['true', 'false']:757                        raise PeachException("Error, default value for Number.signed incorrect.")758                    if Number.defaultSigned == 'true':759                        Number.defaultSigned = True760                    else:761                        Number.defaultSigned = False762                if child.get('valueType') is not None:763                    Number.defaultValueType = self._getAttribute(child, 'valueType')764                    if Number.defaultValueType not in ['string', 'literal', 'hex']:765                        raise PeachException("Error, default value for Number.valueType incorrect.")766            elif child_nodeName == 'String':767                if child.get('valueType') is not None:768                    String.defaultValueType = self._getAttribute(child, 'valueType')769                    if String.defaultValueType not in ['string', 'literal', 'hex']:770                        raise PeachException("Error, default value for String.valueType incorrect.")771                if child.get('lengthType') is not None:772                    String.defaultLengthType = self._getAttribute(child, 'lengthType')773                    if String.defaultLengthType not in ['string', 'literal', 'calc']:774                        raise PeachException("Error, default value for String.lengthType incorrect.")775                if child.get('padCharacter') is not None:776                    String.defaultPadCharacter = child.get('padCharacter')777                if child.get('type') is not None:778                    String.defaultType = self._getAttribute(child, 'type')779                    if String.defaultType not in ['wchar', 'char', 'utf8']:780                        raise PeachException("Error, default value for String.type incorrect.")781                if child.get('nullTerminated') is not None:782                    String.defaultNullTerminated = self._getAttribute(child, 'nullTerminated')783                    if String.defaultNullTerminated not in ['true', 'false']:784                        raise PeachException("Error, default value for String.nullTerminated incorrect.")785                    if String.defaultNullTerminated == 'true':786                        String.defaultNullTerminated = True787                    else:788                        String.defaultNullTerminated = False789    def HandleFixup(self, node, parent):790        """791        Handle Fixup element792        """793        fixup = Fixup(parent)794        params = []795        # class796        if node.get("class") is None:797            raise PeachException("Fixup element missing class attribute")798        fixup.classStr = self._getAttribute(node, "class")799        # children800        for child in node.iterchildren():801            if split_ns(child.tag)[1] == 'Param':802                param = self.HandleParam(child, fixup)803                fixup.append(param)804                params.append([param.name, param.defaultValue])805        code = "PeachXml_" + fixup.classStr + '('806        isFirst = True807        for param in params:808            if not isFirst:809                code += ', '810            else:811                isFirst = False812            code += PeachStr(param[1])813        code += ')'814        fixup.fixup = eval(code, globals(), locals())815        if parent is not None:816            if parent.fixup is not None:817                raise PeachException("Error, data element [%s] already has a fixup." % parent.name)818            parent.fixup = fixup819        return fixup820    def HandlePlacement(self, node, parent):821        """822        Handle Placement element823        """824        placement = Placement(parent)825        placement.after = self._getAttribute(node, "after")826        placement.before = self._getAttribute(node, "before")827        if placement.after is None and placement.before is None:828            raise PeachException("Error: Placement element must have an 'after' or 'before' attribute.")829        if placement.after is not None and placement.before is not None:830            raise PeachException("Error: Placement can only have one of 'after' or 'before' but not both.")831        if parent is not None:832            if parent.placement is not None:833                raise PeachException("Error, data element [%s] already has a placement." % parent.name)834            #print "Setting placement on",parent.name835            parent.placement = placement836            #parent.append(placement)837        return placement838    def HandleRelation(self, node, elem):839        if node.get("type") is None:840            raise PeachException("Relation element does not have type attribute")841        type = self._getAttribute(node, "type")842        of = self._getAttribute(node, "of")843        From = self._getAttribute(node, "from")844        name = self._getAttribute(node, "name")845        when = self._getAttribute(node, "when")846        expressionGet = self._getAttribute(node, "expressionGet")847        expressionSet = self._getAttribute(node, "expressionSet")848        relative = self._getAttribute(node, "relative")849        if of is None and From is None and when is None:850            raise PeachException("Relation element does not have of, from, or when attribute.")851        if type not in ['size', 'count', 'index', 'when', 'offset']:852            raise PeachException("Unknown type value in Relation element")853        relation = Relation(name, elem)854        relation.of = of855        relation.From = From856        relation.type = type857        relation.when = when858        relation.expressionGet = expressionGet859        relation.expressionSet = expressionSet860        if self._getAttribute(node, "isOutputOnly") is not None and self._getAttribute(node, "isOutputOnly") in ["True",861                                                                                                                 "true"]:862            relation.isOutputOnly = True863        if relative is not None:864            if relative.lower() in ["true", "1"]:865                relation.relative = True866                relation.relativeTo = self._getAttribute(node, "relativeTo")867            elif relative.lower() in ["false", "0"]:868                relation.relative = False869                relation.relativeTo = None870            else:871                raise PeachException("Error: Value of Relation relative attribute is not true or false.")872        return relation873    def HandleAnalyzerTopLevel(self, node, elem):874        if node.get("class") is None:875            raise PeachException("Analyzer element must have a 'class' attribute")876        # Locate any arguments877        args = {}878        for child in node.iterchildren():879            if split_ns(child.tag)[1] == 'Param' and child.get('name') is not None:880                args[self._getAttribute(child, 'name')] = self._getAttribute(child, 'value')881        cls = self._getAttribute(node, "class")882        try:883            obj = eval("%s()" % cls)884        except:885            raise PeachException("Error creating analyzer '%s': %s" % (obj, repr(sys.exc_info())))886        if not obj.supportTopLevel:887            raise PeachException("Analyzer '%s' does not support use as top-level element" % cls)888        obj.asTopLevel(self.context, args)889    def HandleCommonDataElementAttributes(self, node, element):890        """891        Handle attributes common to all DataElements such as:892         - minOccurs, maxOccurs893         - mutable894         - isStatic895         - constraint896         - pointer897         - pointerDepth898         - token899        """900        # min/maxOccurs901        self._HandleOccurs(node, element)902        # isStatic/token903        isStatic = self._getAttribute(node, 'isStatic')904        if isStatic is None:905            isStatic = self._getAttribute(node, 'token')906        if isStatic is None or len(isStatic) == 0:907            element.isStatic = False908        elif isStatic.lower() == 'true':909            element.isStatic = True910        elif isStatic.lower() == 'false':911            element.isStatic = False912        else:913            if node.get("isStatic") is not None:914                raise PeachException(915                    "Attribute 'isStatic' has unexpected value [%s], only 'true' and 'false' are supported." % isStatic)916            else:917                raise PeachException(918                    "Attribute 'token' has unexpected value [%s], only 'true' and 'false' are supported." % isStatic)919        # mutable920        mutable = self._getAttribute(node, 'mutable')921        if mutable is None or len(mutable) == 0:922            element.isMutable = True923        elif mutable.lower() == 'true':924            element.isMutable = True925        elif mutable.lower() == 'false':926            element.isMutable = False927        else:928            raise PeachException(929                "Attribute 'mutable' has unexpected value [%s], only 'true' and 'false' are supported." % mutable)930        # pointer931        pointer = self._getAttribute(node, 'pointer')932        if pointer is None:933            pass934        elif pointer.lower() == 'true':935            element.isPointer = True936        elif pointer.lower() == 'false':937            element.isPointer = False938        else:939            raise PeachException(940                "Attribute 'pointer' has unexpected value [%s], only 'true' and 'false' are supported." % pointer)941        # pointerDepth942        if node.get("pointerDepth") is not None:943            element.pointerDepth = self._getAttribute(node, 'pointerDepth')944        # constraint945        element.constraint = self._getAttribute(node, "constraint")946    def _HandleOccurs(self, node, element):947        """948        Grab min, max, and generated Occurs attributes949        """950        if node.get('generatedOccurs') is not None:951            element.generatedOccurs = self._getAttribute(node, 'generatedOccurs')952        else:953            element.generatedOccurs = 10954        occurs = self._getAttribute(node, 'occurs')955        minOccurs = self._getAttribute(node, 'minOccurs')956        maxOccurs = self._getAttribute(node, 'maxOccurs')957        if minOccurs is None:958            minOccurs = 1959        else:960            minOccurs = eval(minOccurs)961        if maxOccurs is None:962            maxOccurs = 1963        else:964            maxOccurs = eval(maxOccurs)965        if minOccurs is not None and maxOccurs is not None:966            element.minOccurs = int(minOccurs)967            element.maxOccurs = int(maxOccurs)968        elif minOccurs is not None and maxOccurs is None:969            element.minOccurs = int(minOccurs)970            element.maxOccurs = 1024971        elif maxOccurs is not None and minOccurs is None:972            element.minOccurs = 0973            element.maxOccurs = int(maxOccurs)974        else:975            element.minOccurs = 1976            element.maxOccurs = 1977        if occurs is not None:978            element.occurs = element.minOccurs = element.maxOccurs = int(occurs)979    def HandleBlock(self, node, parent):980        # name981        if node.get('name') is not None:982            name = self._getAttribute(node, 'name')983        else:984            name = None985        # ref986        if node.get('ref') is not None:987            oldName = self._getAttribute(node, "ref")988            if name is None or len(name) == 0:989                name = Element.getUniqueName()990            # We have a base template991            obj = self.GetRef(self._getAttribute(node, 'ref'), parent)992            block = obj.copy(parent)993            block.name = name994            block.parent = parent995            block.ref = self._getAttribute(node, 'ref')996            # Block may not be a block!997            if getattr(block, 'toXml', None) is None:998                block.toXml = new_instancemethod(dom.Block.toXml, block)999            block.elementType = 'block'1000        else:1001            block = dom.Block(name, parent)1002            block.ref = None1003        #block.node = node1004        # length (in bytes)1005        if node.get('lengthType') is not None and self._getAttribute(node, 'lengthType') == 'calc':1006            block.lengthType = self._getAttribute(node, 'lengthType')1007            block.lengthCalc = self._getAttribute(node, 'length')1008            block.length = -11009        elif node.get('length') is not None:1010            length = self._getAttribute(node, 'length')1011            if length is not None and len(length) != 0:1012                block.length = int(length)1013            else:1014                block.length = None1015        # alignment1016        try:1017            alignment = self._getAttribute(node, 'alignment')1018            if len(alignment) == 0:1019                alignment = None1020        except:1021            alignment = None1022        if alignment is not None:1023            block.isAligned = True1024            block.alignment = int(alignment) ** 21025        # common attributes1026        self.HandleCommonDataElementAttributes(node, block)1027        # children1028        self.HandleDataContainerChildren(node, block)1029        # Switch any references to old name1030        if node.get('ref') is not None:1031            for relation in block._genRelationsInDataModelFromHere():1032                if relation.of == oldName:1033                    relation.of = name1034                elif relation.From == oldName:1035                    relation.From = name1036        # Add to parent1037        parent.append(block)1038        return block1039    def HandleDataContainerChildren(self, node, parent, errorOnUnknown=True):1040        """1041        Handle parsing conatiner children.  This method1042        will handle children of DataElement types for1043        containers like Block, Choice, and Template.1044        Can be used by Custom types to create Custom container1045        types.1046        @type	node: XML Element1047        @param	node: Current XML Node being handled1048        @type	parent: ElementWithChildren1049        @param	parent: Parent of this DataElement1050        @type	errorOnUnknown: Boolean1051        @param	errorOnUnknonw: Should we throw an error on unexpected child node (default True)1052        """1053        # children1054        for child in node.iterchildren():1055            name = self._getAttribute(child, 'name')1056            if name is not None and '.' in name:1057                # Replace a deep node, can only happen if we1058                # have a ref on us.1059                if node.get('ref') is None:1060                    raise PeachException(1061                        "Error, periods (.) are not allowed in element names unless overrideing deep elements when a parent reference (ref). Name: [%s]" % name)1062                # Okay, lets locate the real parent.1063                obj = parent1064                for part in name.split('.')[:-1]:1065                    if part not in obj:1066                        raise PeachException(1067                            "Error, unable to resolve [%s] in deep parent of [%s] override." % (part, name))1068                    obj = obj[part]1069                if obj is None:1070                    raise PeachException("Error, unable to resolve deep parent of [%s] override." % name)1071                # Remove periods from name1072                child.set('name', name.split('.')[-1])1073                # Handle child with new parent.1074                self._HandleDataContainerChildren(node, child, obj, errorOnUnknown)1075            else:1076                self._HandleDataContainerChildren(node, child, parent, errorOnUnknown)1077    def _HandleDataContainerChildren(self, node, child, parent, errorOnUnknown=True):1078        node_nodeName = split_ns(node.tag)[1]1079        child_nodeName = split_ns(child.tag)[1]1080        if child_nodeName == 'Block':1081            self.HandleBlock(child, parent)1082        elif child_nodeName == 'String':1083            self.HandleString(child, parent)1084        elif child_nodeName == 'Number':1085            self.HandleNumber(child, parent)1086        elif child_nodeName == 'Flags':1087            self.HandleFlags(child, parent)1088        elif child_nodeName == 'Flag':1089            self.HandleFlag(child, parent)1090        elif child_nodeName == 'Blob':1091            self.HandleBlob(child, parent)1092        elif child_nodeName == 'Choice':1093            self.HandleChoice(child, parent)1094        elif child_nodeName == 'Transformer':1095            parent.transformer = self.HandleTransformer(child, parent)1096        elif child_nodeName == 'Relation':1097            relation = self.HandleRelation(child, parent)1098            parent.relations.append(relation)1099        elif child_nodeName == 'Fixup':1100            self.HandleFixup(child, parent)1101        elif child_nodeName == 'Placement':1102            self.HandlePlacement(child, parent)1103        elif child_nodeName == 'Hint':1104            self.HandleHint(child, parent)1105        elif child_nodeName == 'Seek':1106            self.HandleSeek(child, parent)1107        elif child_nodeName == 'Custom':1108            self.HandleCustom(child, parent)1109        elif child_nodeName == 'Asn1':1110            self.HandleAsn1(child, parent)1111        elif child_nodeName == 'XmlElement':1112            # special XmlElement reference1113            if child.get('ref') is not None:1114                # This is our special case, if we ref we suck the children1115                # of the ref into our selves.  This is tricky!1116                # get and copy our ref1117                obj = self.GetRef(self._getAttribute(child, 'ref'), parent.parent)1118                newobj = obj.copy(parent)1119                newobj.parent = None1120                # first verify all children are XmlElement or XmlAttribute1121                for subchild in newobj:1122                    if not isinstance(subchild, XmlElement) and not isinstance(subchild, XmlAttribute):1123                        raise PeachException(1124                            "Error, special XmlElement ref case, reference must only have Xml elements!! (%s,%s,%s)" % (1125                                subchild.parent.name, subchild.name, subchild))1126                # now move over children1127                for subchild in newobj:1128                    parent.append(subchild)1129                # remove replaced element1130                if self._getAttribute(child, 'name') in parent:1131                    del parent[self._getAttribute(child, 'name')]1132            else:1133                self.HandleXmlElement(child, parent)1134        elif child_nodeName == 'XmlAttribute':1135            self.HandleXmlAttribute(child, parent)1136        elif errorOnUnknown:1137            raise PeachException(1138                PeachStr("found unexpected node [%s] in Element: %s" % (child_nodeName, node_nodeName)))1139    def HandleMutators(self, node, parent):1140        # name1141        name = self._getAttribute(node, 'name')1142        mutators = dom.Mutators(name, parent)1143        # children1144        for child in node.iterchildren():1145            child_nodeName = split_ns(child.tag)[1]1146            if child_nodeName != 'Mutator':1147                raise PeachException(PeachStr("Found unexpected node in Mutators element: %s" % child_nodeName))1148            if child.get('class') is None:1149                raise PeachException("Mutator element does not have required class attribute")1150            mutator = Mutator(self._getAttribute(child, 'class'), mutators)1151            mutators.append(mutator)1152        parent.append(mutators)1153        return mutators1154    def HandleChoice(self, node, parent):1155        # name1156        name = self._getAttribute(node, 'name')1157        # ref1158        if node.get('ref') is not None:1159            if name is None or len(name) == 0:1160                name = Element.getUniqueName()1161            # We have a base template1162            obj = self.GetRef(self._getAttribute(node, 'ref'), parent)1163            #print "About to deep copy: ", obj, " for ref: ", self._getAttribute(node, 'ref')1164            block = obj.copy(parent)1165            block.name = name1166            block.parent = parent1167            block.ref = self._getAttribute(node, 'ref')1168        else:1169            block = Choice(name, parent)1170            block.ref = None1171        block.elementType = 'choice'1172        # length (in bytes)1173        if self._getAttribute(node, 'lengthType') == 'calc':1174            block.lengthType = self._getAttribute(node, 'lengthType')1175            block.lengthCalc = self._getAttribute(node, 'length')1176            block.length = -11177        elif node.get('length') is not None:1178            length = self._getAttribute(node, 'length')1179            if length is not None and len(length) != 0:1180                block.length = int(length)1181            else:1182                block.length = None1183        # common attributes1184        self.HandleCommonDataElementAttributes(node, block)1185        # children1186        self.HandleDataContainerChildren(node, block)1187        parent.append(block)1188        return block1189    def HandleAsn1(self, node, parent):1190        # name1191        name = self._getAttribute(node, 'name')1192        # ref1193        if node.get('ref') is not None:1194            raise PeachException("Asn1 element does not yet support ref!")1195            #1196            #if name == None or len(name) == 0:1197            #	name = Element.getUniqueName()1198            #1199            ## We have a base template1200            #obj = self.GetRef( self._getAttribute(node, 'ref'), parent )1201            #1202            ##print "About to deep copy: ", obj, " for ref: ", self._getAttribute(node, 'ref')1203            #1204            #block = obj.copy(parent)1205            #block.name = name1206            #block.parent = parent1207            #block.ref = self._getAttribute(node, 'ref')1208        else:1209            block = Asn1Type(name, parent)1210            block.ref = None1211        # encode type1212        if node.get("encode"):1213            block.encodeType = node.get("encode")1214        # asn1Type1215        if node.get("type") is None:1216            raise PeachException("Error, all Asn1 elements must have 'type' attribute.")1217        block.asn1Type = node.get("type")1218        # Tag Stuff1219        if node.get("tagNumber") is not None:1220            try:1221                block.tagClass = Asn1Type.ASN1_TAG_CLASS_MAP[self._getAttribute(node, "tagClass").lower()]1222                block.tagFormat = Asn1Type.ASN1_TAG_TYPE_MAP[self._getAttribute(node, "tagFormat").lower()]1223                block.tagCategory = self._getAttribute(node, "tagCategory").lower()1224                block.tagNumber = int(self._getAttribute(node, "tagNumber"))1225            except:1226                raise PeachException(1227                    "Error, When using tags you must specify 'tagClass', 'tagFormat', 'tagCategory', and 'tagNumber'.")1228        # common attributes1229        self.HandleCommonDataElementAttributes(node, block)1230        # children1231        self.HandleDataContainerChildren(node, block)1232        parent.append(block)1233        return block1234    def HandleXmlElement(self, node, parent):1235        # name1236        name = self._getAttribute(node, 'name')1237        block = XmlElement(name, parent)1238        # elementName1239        block.elementName = self._getAttribute(node, "elementName")1240        if block.elementName is None:1241            raise PeachException("Error: XmlElement without elementName attribute.")1242        # ns1243        block.xmlNamespace = self._getAttribute(node, "ns")1244        # length (in bytes)1245        if self._getAttribute(node, 'lengthType') == 'calc':1246            block.lengthType = self._getAttribute(node, 'lengthType')1247            block.lengthCalc = self._getAttribute(node, 'length')1248            block.length = -11249        elif node.get('length') is not None:1250            length = self._getAttribute(node, 'length')1251            if length is not None and len(length) != 0:1252                block.length = int(length)1253            else:1254                block.length = None1255        # common attributes1256        self.HandleCommonDataElementAttributes(node, block)1257        # children1258        self.HandleDataContainerChildren(node, block)1259        parent.append(block)1260        return block1261    def HandleXmlAttribute(self, node, parent):1262        # name1263        name = self._getAttribute(node, 'name')1264        block = XmlAttribute(name, parent)1265        # elementName1266        block.attributeName = self._getAttribute(node, "attributeName")1267        # ns1268        block.xmlNamespace = self._getAttribute(node, "ns")1269        # length (in bytes)1270        if self._getAttribute(node, 'lengthType') == 'calc':1271            block.lengthType = self._getAttribute(node, 'lengthType')1272            block.lengthCalc = self._getAttribute(node, 'length')1273            block.length = -11274        elif node.get('length') is not None:1275            length = self._getAttribute(node, 'length')1276            if length is not None and len(length) != 0:1277                block.length = int(length)1278            else:1279                block.length = None1280        # common attributes1281        self.HandleCommonDataElementAttributes(node, block)1282        # children1283        self.HandleDataContainerChildren(node, block)1284        parent.append(block)1285        return block1286    def _getAttribute(self, node, name):1287        attr = node.get(name)1288        if attr is None:1289            return None1290        return PeachStr(attr)1291    def _getValueType(self, node):1292        valueType = self._getAttribute(node, 'valueType')1293        if valueType is None:1294            return 'string'1295        return valueType1296    def HandleString(self, node, parent):1297        # name1298        name = self._getAttribute(node, 'name')1299        string = String(name, parent)1300        # value1301        string.defaultValue = self.GetValueFromNodeString(node)1302        string.valueType = self._getValueType(node)1303        string.defaultValue = self._HandleValueTypeString(string.defaultValue, string.valueType)1304        # tokens1305        string.tokens = self._getAttribute(node, 'tokens')1306        # padCharacter1307        if node.get('padCharacter') is not None:1308            val = node.get('padCharacter')1309            val = val.replace("'", "\\'")1310            string.padCharacter = eval("u'''" + val + "'''")1311        # type1312        if node.get('type') is not None:1313            type = self._getAttribute(node, 'type')1314            if type is None or len(type) == 0:1315                string.type = 'char'1316            elif not (type in ['char', 'wchar', 'utf8', 'utf-8', 'utf-16le', 'utf-16be']):1317                raise PeachException("Unknown type of String: %s" % type)1318            else:1319                string.type = type1320        # nullTerminated (optional)1321        if node.get('nullTerminated') is not None:1322            nullTerminated = self._getAttribute(node, 'nullTerminated')1323            if nullTerminated is None or len(nullTerminated) == 0:1324                nullTerminated = 'false'1325            if nullTerminated.lower() == 'true':1326                string.nullTerminated = True1327            elif nullTerminated.lower() == 'false':1328                string.nullTerminated = False1329            else:1330                raise PeachException("nullTerminated should be true or false")1331        # length (bytes)1332        if self._getAttribute(node, 'lengthType') == 'calc':1333            string.lengthType = self._getAttribute(node, 'lengthType')1334            string.lengthCalc = self._getAttribute(node, 'length')1335            string.length = -11336        elif node.get('length') is not None:1337            length = self._getAttribute(node, 'length')1338            if length is None or len(length) == 0:1339                length = None1340            try:1341                if length is not None:1342                    string.length = int(length)1343                else:1344                    string.length = None1345            except:1346                raise PeachException("length must be a number or missing %s" % length)1347        # Analyzer1348        string.analyzer = self._getAttribute(node, 'analyzer')1349        # common attributes1350        self.HandleCommonDataElementAttributes(node, string)1351        # Handle any common children1352        self.HandleCommonTemplate(node, string)1353        parent.append(string)1354        return string1355    def HandleNumber(self, node, parent):1356        # name1357        name = self._getAttribute(node, 'name')1358        number = Number(name, parent)1359        # value1360        number.defaultValue = PeachStr(self.GetValueFromNodeNumber(node))1361        number.valueType = self._getValueType(node)1362        if number.defaultValue is not None:1363            try:1364                number.defaultValue = int(number.defaultValue)1365            except:1366                raise PeachException("Error: The default value for <Number> elements must be an integer.")1367        # size (bits)1368        if node.get('size') is not None:1369            size = self._getAttribute(node, 'size')1370            if size is None:1371                raise PeachException(1372                    "Number element %s is missing the 'size' attribute which is required." % number.name)1373            number.size = int(size)1374            if not number.size in number._allowedSizes:1375                raise PeachException("invalid size")1376        # endian (optional)1377        if node.get('endian') is not None:1378            number.endian = self._getAttribute(node, 'endian')1379            if number.endian == 'network':1380                number.endian = 'big'1381            if number.endian != 'little' and number.endian != 'big':1382                raise PeachException("invalid endian %s" % number.endian)1383        # signed (optional)1384        if node.get('signed') is not None:1385            signed = self._getAttribute(node, 'signed')1386            if signed is None or len(signed) == 0:1387                signed = Number.defaultSigned1388            if signed.lower() == 'true':1389                number.signed = True1390            elif signed.lower() == 'false':1391                number.signed = False1392            else:1393                raise PeachException("signed must be true or false")1394        # common attributes1395        self.HandleCommonDataElementAttributes(node, number)1396        # Handle any common children1397        self.HandleCommonTemplate(node, number)1398        parent.append(number)1399        return number1400    def HandleFlags(self, node, parent):1401        name = self._getAttribute(node, 'name')1402        flags = dom.Flags(name, parent)1403        #flags.node = node1404        # length (in bits)1405        length = self._getAttribute(node, 'size')1406        flags.length = int(length)1407        if flags.length % 2 != 0:1408            raise PeachException("length must be multiple of 2")1409        if flags.length not in [8, 16, 24, 32, 64]:1410            raise PeachException("Flags size must be one of 8, 16, 24, 32, or 64.")1411        # endian1412        if node.get('endian') is not None:1413            flags.endian = self._getAttribute(node, 'endian')1414            if not ( flags.endian == 'little' or flags.endian == 'big' ):1415                raise PeachException("Invalid endian type on Flags element")1416        # rightToLeft1417        if node.get('rightToLeft') is not None:1418            if self._getAttribute(node, 'rightToLeft').lower() == "true":1419                flags.rightToLeft = True1420            elif self._getAttribute(node, 'rightToLeft').lower() == "false":1421                flags.rightToLeft = False1422            else:1423                raise PeachException("Flags attribute rightToLeft must be 'true' or 'false'.")1424        # padding1425        if node.get('padding') is not None:1426            if self._getAttribute(node, 'padding').lower() == "true":1427                flags.padding = True1428            elif self._getAttribute(node, 'padding').lower() == "false":1429                flags.padding = False1430            else:1431                raise PeachException("Flags attribute padding must be 'true' or 'false'.")1432        # constraint1433        flags.constraint = self._getAttribute(node, "constraint")1434        # children1435        for child in node.iterchildren():1436            child_nodeName = split_ns(child.tag)[1]1437            if child_nodeName == 'Flag':1438                childName = self._getAttribute(child, 'name')1439                if childName is not None:1440                    if childName in flags:1441                        raise PeachException("Error, found duplicate Flag name in Flags set [%s]" % flags.name)1442                self.HandleFlag(child, flags)1443            elif child_nodeName == 'Relation':1444                self.HandleRelation(child, flags)1445            else:1446                raise PeachException(PeachStr("found unexpected node in Flags: %s" % child_nodeName))1447        parent.append(flags)1448        return flags1449    def HandleFlag(self, node, parent):1450        name = self._getAttribute(node, 'name')1451        flag = Flag(name, parent)1452        #flag.node = node1453        # value1454        flag.defaultValue = PeachStr(self.GetValueFromNode(node))1455        flag.valueType = self._getValueType(node)1456        # position (in bits)1457        position = self._getAttribute(node, 'position')1458        flag.position = int(position)1459        # length (in bits)1460        length = self._getAttribute(node, 'size')1461        flag.length = int(length)1462        if flag.position > parent.length:1463            raise PeachException("Invalid position, parent not big enough")1464        if flag.position + flag.length > parent.length:1465            raise PeachException("Invalid length, parent not big enough")1466        # Handle any common children1467        self.HandleCommonTemplate(node, flag)1468        # Handle common data elements attributes1469        self.HandleCommonDataElementAttributes(node, flag)1470        # rest1471        parent.append(flag)1472        return flag1473    def HandleBlob(self, node, parent):1474        name = self._getAttribute(node, 'name')1475        blob = Blob(name, parent)1476        # value1477        blob.defaultValue = PeachStr(self.GetValueFromNode(node))1478        blob.valueType = self._getValueType(node)1479        # length (in bytes)1480        if self._getAttribute(node, 'lengthType') == 'calc':1481            blob.lengthType = self._getAttribute(node, 'lengthType')1482            blob.lengthCalc = self._getAttribute(node, 'length')1483            blob.length = -11484        elif node.get('length') is not None:1485            length = self._getAttribute(node, 'length')1486            if length is not None and len(length) != 0:1487                blob.length = int(length)1488            else:1489                blob.length = None1490        # padValue1491        if node.get('padValue') is not None:1492            blob.padValue = self._getAttribute(node, 'padValue')1493        else:1494            blob.padValue = "\0"1495        # Analyzer1496        blob.analyzer = self._getAttribute(node, 'analyzer')1497        # common attributes1498        self.HandleCommonDataElementAttributes(node, blob)1499        # Handle any common children1500        self.HandleCommonTemplate(node, blob)1501        parent.append(blob)1502        return blob1503    def HandleCustom(self, node, parent):1504        name = self._getAttribute(node, 'name')1505        cls = self._getAttribute(node, 'class')1506        code = "PeachXml_%s(name, parent)" % cls1507        custom = eval(code, globals(), locals())1508        #custom.node = node1509        # value1510        custom.defaultValue = PeachStr(self.GetValueFromNode(node))1511        custom.valueType = self._getValueType(node)1512        # Hex handled elsewere.1513        if custom.valueType == 'literal':1514            custom.defaultValue = PeachStr(eval(custom.defaultValue))1515        # common attributes1516        self.HandleCommonDataElementAttributes(node, custom)1517        # Handle any common children1518        self.HandleCommonTemplate(node, custom)1519        # constraint1520        custom.constraint = self._getAttribute(node, "constraint")1521        # Custom parsing1522        custom.handleParsing(node)1523        # Done1524        parent.append(custom)1525        return custom1526    def HandleSeek(self, node, parent):1527        """1528        Parse a <Seek> element, part of a data model.1529        """1530        seek = Seek(None, parent)1531        #seek.node = node1532        seek.expression = self._getAttribute(node, 'expression')1533        seek.position = self._getAttribute(node, 'position')1534        seek.relative = self._getAttribute(node, 'relative')1535        if seek.relative is not None:1536            seek.relative = int(seek.relative)1537        if seek.position is not None:1538            seek.position = int(seek.position)1539        if seek.expression is None and seek.position is None and seek.relative is None:1540            raise PeachException("Error: <Seek> element must have an expression, position, or relative attribute.")1541        parent.append(seek)1542        return seek1543    def HandleData(self, node, parent):1544        # attribute: name1545        name = self._getAttribute(node, 'name')1546        # attribute: ref1547        if node.get('ref') is not None:1548            if name is None or not len(name):1549                name = Element.getUniqueName()1550            data = self.GetDataRef(self._getAttribute(node, 'ref')).copy(parent)1551            data.name = name1552        else:1553            data = Data(name)1554            if not isinstance(parent, Action) and (name is None or not len(name)):1555                raise PeachException("<Data> must have a name attribute!")1556        data.elementType = 'data'1557        # attribute: maxFileSize1558        if node.get('maxFileSize') is not None:1559            data.maxFileSize = int(self._getAttribute(node, 'maxFileSize'))1560        # attribute: fileName1561        if node.get('fileName') is not None:1562            data.fileName = self._getAttribute(node, 'fileName')1563            if data.fileName.find('*') != -1:1564                data.fileGlob = data.fileName1565                for fpath in glob.glob(data.fileGlob):1566                    if data.is_valid(fpath):1567                        data.fileName = fpath1568                data.multipleFiles = True1569            elif os.path.isdir(data.fileName):1570                data.folderName = data.fileName1571                for fname in os.listdir(data.folderName):1572                    fpath = os.path.join(data.folderName, fname)1573                    if data.is_valid(fpath):1574                        data.fileName = fpath1575                data.multipleFiles = True1576        if not os.path.isfile(data.fileName):1577            raise PeachException("No sample data found matching requirements of <Data> element.")1578        # attribute: recurse1579        if node.get('recurse') is not None:1580            data.recurse = bool(self._getAttribute(node, 'recurse'))1581        # attribute: switchCount1582        if node.get('switchCount') is not None:1583            data.switchCount = int(self._getAttribute(node, 'switchCount'))1584        else:1585            data.switchCount = None1586        # attribute: expression1587        if node.get('expression') is not None:1588            if data.fileName is not None:1589                raise PeachException("<Data> can not have both a fileName and expression attribute.")1590            data.expression = self._getAttribute(node, 'expression')1591        # children1592        for child in node.iterchildren():1593            child_nodeName = split_ns(child.tag)[1]1594            if child_nodeName == 'Field':1595                if data.fileName is not None or data.expression is not None:1596                    raise PeachException("<Data> can not have a fileName or expression attribute along with Field "1597                                         "child elements.")1598                self.HandleField(child, data)1599            else:1600                raise PeachException("Found unexpected node inside <Data>: %s" % child_nodeName)1601        return data1602    def HandleField(self, node, parent):1603        # name1604        if node.get('name') is None:1605            raise PeachException("No attribute name found on field element")1606        name = self._getAttribute(node, 'name')1607        # value1608        if node.get('value') is None:1609            raise PeachException("No attribute value found on Field element")1610        value = self._getAttribute(node, 'value')1611        field = Field(name, value, parent)1612        field.value = PeachStr(self.GetValueFromNode(node))1613        field.valueType = self._getValueType(node)1614        if field.name in parent:1615            parent[field.name] = field1616        else:1617            parent.append(field)1618        return field1619    # Handlers for Agent ###################################################1620    def HandleAgent(self, node, parent):1621        # name1622        name = self._getAttribute(node, 'name')1623        # ref1624        if node.get('ref') is not None:1625            if name is None or len(name) == 0:1626                name = Element.getUniqueName()1627            obj = self.GetRef(self._getAttribute(node, 'ref'))1628            agent = obj.copy(parent)1629            agent.name = name1630            agent.ref = self._getAttribute(node, 'ref')1631        else:1632            agent = Agent(name, parent)1633        #agent.node = node1634        agent.description = self._getAttribute(node, 'description')1635        agent.location = self._getAttribute(node, 'location')1636        if agent.location is None or len(agent.location) == 0:1637            agent.location = "LocalAgent"1638            #raise PeachException("Error: Agent definition must include location attribute.")1639        agent.password = self._getAttribute(node, 'password')1640        if agent.password is not None and len(agent.password) == 0:1641            agent.password = None1642        for child in node.iterchildren():1643            child_nodeName = split_ns(child.tag)[1]1644            if child_nodeName == 'Monitor':1645                if not self._getBooleanAttribute(child, "enabled"):1646                    logging.info('Monitor  "%s" is deactivated.' % self._getAttribute(child, "class"))1647                    continue1648                if child.get("platform") is not None:1649                    validOS = [x for x in self._getAttribute(child, "platform").split(",") if x == sys.platform]1650                    if not validOS:1651                        logging.debug('Monitor "%s" for %s is not supported on this platform.' %1652                                     (self._getAttribute(child, "class"), self._getAttribute(child, "platform")))1653                        continue1654                agent.append(self.HandleMonitor(child, agent))1655                logging.info('Monitor "%s" attached.' % self._getAttribute(child, "class"))1656            elif child_nodeName == 'PythonPath':1657                p = self.HandlePythonPath(child, agent)1658                agent.append(p)1659            elif child_nodeName == 'Import':1660                p = self.HandleImport(child, agent)1661                agent.append(p)1662            else:1663                raise PeachException("Found unexpected child of Agent element")1664        ## A remote publisher might be in play1665        #if len(agent) < 1:1666        #	raise Exception("Agent must have at least one Monitor child.")1667        return agent1668    def HandleMonitor(self, node, parent):1669        """1670        Handle Monitor element1671        """1672        name = self._getAttribute(node, 'name')1673        monitor = Monitor(name, parent)1674        # class1675        if node.get("class") is None:1676            raise PeachException("Monitor element missing class attribute")1677        monitor.classStr = self._getAttribute(node, "class")1678        # children1679        for child in node.iterchildren():1680            child_nodeName = split_ns(child.tag)[1]1681            if not child_nodeName == 'Param':1682                raise PeachException(PeachStr("Unexpected Monitor child node: %s" % child_nodeName))1683            param = self.HandleParam(child, parent)1684            monitor.params[param.name] = param.defaultValue1685        return monitor1686    # Handlers for Test ###################################################1687    def HandleTest(self, node, parent):1688        # name1689        name = self._getAttribute(node, 'name')1690        # ref1691        if node.get('ref') is not None:1692            if name is None or len(name) == 0:1693                name = Element.getUniqueName()1694            obj = self.GetRef(self._getAttribute(node, 'ref'), None, 'tests')1695            test = obj.copy(parent)1696            test.name = name1697            test.ref = self._getAttribute(node, 'ref')1698        else:1699            test = Test(name, parent)1700        #test.node = node1701        if node.get('description') is not None:1702            test.description = self._getAttribute(node, 'description')1703        test.mutators = None1704        for child in node.iterchildren():1705            child_nodeName = split_ns(child.tag)[1]1706            if child_nodeName == 'Publisher':1707                if not test.publishers:1708                    test.publishers = []1709                pub = self.HandlePublisher(child, test)1710                test.publishers.append(pub)1711                test.append(pub.domPublisher)1712            elif child_nodeName == 'Agent':1713                if child.get('ref') is not None:1714                    agent = self.GetRef(self._getAttribute(child, 'ref'), None, 'agents')1715                if agent is None:1716                    raise PeachException(PeachStr("Unable to locate agent %s specified in Test element %s" % (1717                        self._getAttribute(child, 'ref'), name)))1718                test.append(agent.copy(test))1719            elif child_nodeName == 'StateMachine' or child_nodeName == 'StateModel':1720                if child.get('ref') is None:1721                    raise PeachException("StateMachine element in Test declaration must have a ref attribute.")1722                stateMachine = self.GetRef(self._getAttribute(child, 'ref'), None, 'children')1723                if stateMachine is None:1724                    raise PeachException("Unable to locate StateMachine [%s] specified in Test [%s]" % (1725                        str(self._getAttribute(child, 'ref')), name))1726                #print "*** StateMachine: ", stateMachine1727                test.stateMachine = stateMachine.copy(test)1728                test.append(test.stateMachine)1729                path = None1730                for child2 in child.iterchildren():1731                    child2_nodeName = split_ns(child.tag)[1]1732                    if child2_nodeName == 'Path':1733                        path = self.HandlePath(child2, test.stateMachine)1734                        test.stateMachine.append(path)1735                    elif child2_nodeName == 'Stop':1736                        if path is None:1737                            raise PeachException("Stop element must be used after a Path element.")1738                        path.stop = True1739                        # Do not accept anything after Stop element ;)1740                        break1741                    elif child2_nodeName == 'Strategy':1742                        strategy = self.HandleStrategy(child2, test.stateMachine)1743                        test.stateMachine.append(strategy)1744                    else:1745                        raise PeachException("Unexpected node %s" % child2_nodeName)1746            elif child_nodeName == 'Mutator':1747                if child.get('class') is None:1748                    raise PeachException("Mutator element does not have required class attribute")1749                mutator = Mutator(self._getAttribute(child, 'class'), test)1750                if not test.mutators:1751                    test.mutators = Mutators(None, test)1752                mutator.parent = test.mutators1753                test.mutators.append(mutator)1754            elif child_nodeName == 'Include' or child_nodeName == 'Exclude':1755                self._HandleIncludeExclude(child, test)1756            elif child_nodeName == 'Strategy':1757                if self._getBooleanAttribute(child, "enabled"):1758                    test.mutator = self.HandleFuzzingStrategy(child, test)1759            else:1760                raise PeachException("Found unexpected child of Test element")1761        if test.mutator is None:1762            test.mutator = MutationStrategy.DefaultStrategy(None, test)1763        if test.mutators is None:1764            # Add the default mutators instead of erroring out1765            test.mutators = self._locateDefaultMutators()1766        if test.template is None and test.stateMachine is None:1767            raise PeachException(PeachStr("Test %s does not have a Template or StateMachine defined" % name))1768        if len(test.publishers) == 0:1769            raise PeachException(PeachStr("Test %s does not have a publisher defined!" % name))1770        if test.template is not None and test.stateMachine is not None:1771            raise PeachException(PeachStr(1772                "Test %s has both a Template and StateMachine defined.  Only one of them can be defined at a time." % name))1773        # Now mark Mutatable(being fuzzed) elements1774        # instructing on inclusions/exlusions1775        test.markMutatableElements(node)1776        return test1777    def HandleFuzzingStrategy(self, node, parent):1778        """1779        Handle parsing <Strategy> element that is a child of1780        <Test>1781        """1782        # name1783        name = self._getAttribute(node, 'name')1784        # class1785        cls = self._getAttribute(node, 'class')1786        # TODO why does this not work?1787        #return globals()["PeachXml_" + cls](node, parent)1788        exec("strategy = PeachXml_%s(node, parent)" % cls)1789        return strategy1790    def HandlePath(self, node, parent):1791        if node.get('ref') is None:1792            raise PeachException("Parser: Test::StateModel::Path missing ref attribute")1793        stateMachine = parent1794        ref = self._getAttribute(node, 'ref')1795        state = self.GetRef(ref, stateMachine, None)1796        path = Path(ref, parent)1797        for child in node.iterchildren():1798            child_nodeName = split_ns(child.tag)[1]1799            if child_nodeName == 'Include' or child_nodeName == 'Exclude':1800                self._HandleIncludeExclude(child, state)1801            elif child_nodeName == 'Data':1802            # Handle Data elements at Test-level1803                data = self.HandleData(child, path)1804                #data.node = child1805                actions = [child for child in state if child.elementType == 'action']1806                for action in actions:1807                    cracker = DataCracker(action.getRoot())1808                    cracker.optmizeModelForCracking(action.template)1809                    action.template.setDefaults(data, self.dontCrack)1810            elif child_nodeName not in ['Mutator']:1811                raise PeachException("Found unexpected child of Path element")1812        return path1813    def _HandleIncludeExclude(self, node, parent):1814        ref = None1815        isExclude = split_ns(node.tag)[1] != 'Exclude'1816        if node.get('ref') is not None and node.get('xpath') is not None:1817            raise PeachException("Include/Exclude node can only have one of either ref or xpath attributes.")1818        if node.get('xpath') is not None:1819            xpath = self._getAttribute(node, 'xpath')1820        else:1821            ref = None1822            if node.get('ref') is not None:1823                ref = self._getAttribute(node, 'ref').replace('.', '/')1824            xpath = self._retrieveXPath(ref, node.getparent())1825        test = self._getTest(parent)1826        test.mutatables.append([isExclude, xpath])1827    def _getTest(self, element):1828        if element is None:1829            return None1830        if element.elementType == 'test':1831            return element1832        return self._getTest(element.parent)1833    def _retrieveXPath(self, xpath, node):1834        if split_ns(node.tag)[1] == 'Test':1835            if xpath is None:1836                return "//*"1837            else:1838                return "//%s" % xpath1839        if node.get('ref') is None:1840            raise PeachException("All upper elements must have a ref attribute. Cannot retrieve relative XPath.")1841        ref = self._getAttribute(node, 'ref')1842        if xpath is not None:1843            xpath = ref + "/" + xpath1844        else:1845            xpath = ref1846        return self._retrieveXPath(xpath, node.getparent())1847    def HandleStrategy(self, node, parent):1848        # class1849        if node.get("class") is None:1850            raise PeachException("Strategy element missing class attribute")1851        classStr = self._getAttribute(node, "class")1852        strategy = Strategy(classStr, parent)1853        # children1854        for child in node.iterchildren():1855            child_nodeName = split_ns(child.tag)[1]1856            if not child_nodeName == 'Param':1857                raise PeachException(PeachStr("Unexpected Strategy child node: %s" % child_nodeName))1858            param = self.HandleParam(child, parent)1859            strategy.params[param.name] = eval(param.defaultValue)1860        return strategy1861    def _locateDefaultMutators(self, obj=None):1862        """1863        Look for a default set of mutators.  We will follow this1864        search pattern:1865        1. Look at our self (context) level1866        2. Look at our imported namespaces1867        3. Recerse into namespaces (sub namespaces, etc)1868        This means a <Mutators> element in the top level XML file will1869        get precidence over the defaults.xml file which is included into1870        a namepsace.1871        """1872        if obj is None:1873            obj = self.context1874        # First look at us1875        if obj.mutators is not None:1876            return obj.mutators1877        # Now look at namespaces1878        for n in obj:1879            if n.elementType == 'namespace':1880                if n.ns.mutators is not None:1881                    return n.ns.mutators1882        # Now look inside namespace1883        for n in obj:1884            if n.elementType == 'namespace':1885                m = self._locateDefaultMutators(n.ns)1886                if m is not None:1887                    return m1888        # YUCK1889        raise PeachException("Could not locate default set of Mutators to use.  Please fix this!")1890    def HandleRun(self, node, parent):1891        haveLogger = False1892        # name1893        name = None1894        if node.get('name') is not None:1895            name = self._getAttribute(node, 'name')1896        run = Run(name, parent)1897        #run.node = node1898        run.description = self._getAttribute(node, 'description')1899        if node.get('waitTime') is not None:1900            run.waitTime = float(self._getAttribute(node, 'waitTime'))1901        for child in node.iterchildren():1902            child_nodeName = split_ns(child.tag)[1]1903            if child_nodeName == 'Test':1904                test = None1905                if child.get('ref') is not None:1906                    test = self.GetRef(self._getAttribute(child, 'ref'), None, 'tests')1907                if test is None:1908                    raise PeachException(1909                        PeachStr("Unable to locate tests %s specified in Run element %s" % (testsName, name)))1910                test = test.copy(run)1911                run.tests.append(test)1912                run.append(test)1913            elif child_nodeName == 'Logger':1914                if not self._getBooleanAttribute(child, "enabled"):1915                    continue1916                loggerName = self._getAttribute(child, "class")1917                try:1918                    logger = self.HandleLogger(child, run)1919                except Exception as msg:1920                    logging.warning(highlight.warning("Unable to attach %s: %s" % (loggerName, msg)))1921                    continue1922                logging.info('Logger "%s" attached.' % loggerName)1923                run.append(logger)1924                haveLogger = True1925            else:1926                raise PeachException("Found unexpected child of Run element")1927        if len(run.tests) == 0:1928            raise PeachException(PeachStr("Run %s does not have any tests defined!" % name))1929        if not haveLogger:1930            logging.warning("Run '%s' does not have logging configured!" % name)1931        return run1932    def HandlePublisher(self, node, parent):1933        params = []1934        publisher = Publisher()1935        # class1936        if node.get("class") is None:1937            raise PeachException("Publisher element missing class attribute")1938        if len(node.get("class")) == 0:1939            raise PeachException("Publisher class attribute is empty")1940        publisher.classStr = publisherClass = self._getAttribute(node, "class")1941        if node.get("name") is not None:1942            publisher.name = self._getAttribute(node, "name")1943        # children1944        for child in node.iterchildren():1945            child_nodeName = split_ns(child.tag)[1]1946            if child.get("name") is None:1947                raise PeachException("Publisher element missing name attribute")1948            if child.get("value") is None:1949                raise PeachException("Publisher element missing value attribute")1950            if child.get("valueType") is None:1951                valueType = "string"1952            else:1953                valueType = self._getAttribute(child, "valueType")1954            name = self._getAttribute(child, "name")1955            value = self._getAttribute(child, "value")1956            param = Param(publisher)1957            param.name = name1958            param.defaultValue = PeachStr(value)1959            param.valueType = valueType1960            if valueType == 'string':1961                # create a literal out of a string value1962                value = "'''" + value + "'''"1963            elif valueType == 'hex':1964                ret = ''1965                valueLen = len(value) + 11966                while valueLen > len(value):1967                    valueLen = len(value)1968                    for i in range(len(self._regsHex)):1969                        match = self._regsHex[i].search(value)1970                        if match is not None:1971                            while match is not None:1972                                ret += '\\x' + match.group(2)1973                                value = self._regsHex[i].sub('', value)1974                                match = self._regsHex[i].search(value)1975                            break1976                value = "'" + ret + "'"1977            publisher.append(param)1978            params.append([name, value])1979        code = "PeachXml_%s(%s)" % (publisherClass, ",".join(str(v) for _,v in params))1980        pub = eval(code, globals(), locals())1981        pub.domPublisher = publisher1982        pub.parent = parent1983        return pub1984    def HandleLogger(self, node, parent):1985        params = {}1986        logger = Logger(parent)1987        #logger.node = node1988        # class1989        if node.get("class") is None:1990            raise PeachException("Logger element missing class attribute")1991        logger.classStr = self._getAttribute(node, "class")1992        # children1993        for child in node.iterchildren():1994            child_nodeName = split_ns(child.tag)[1]1995            if child.get("name") is None:1996                raise PeachException("Logger element missing name attribute")1997            if child.get("value") is None:1998                raise PeachException("Logger element missing value attribute")1999            if child.get("valueType") is None:2000                valueType = "string"2001            else:2002                valueType = self._getAttribute(child, "valueType")2003            name = self._getAttribute(child, "name")2004            value = self._getAttribute(child, "value")2005            param = Param(logger)2006            param.name = name2007            param.defaultValue = PeachStr(value)2008            param.valueType = valueType2009            if valueType == 'string':2010                # create a literal out of a string value2011                value = "'''" + value + "'''"2012            elif valueType == 'hex':2013                ret = ''2014                valueLen = len(value) + 12015                while valueLen > len(value):2016                    valueLen = len(value)2017                    for i in range(len(self._regsHex)):2018                        match = self._regsHex[i].search(value)2019                        if match is not None:2020                            while match is not None:2021                                ret += '\\x' + match.group(2)2022                                value = self._regsHex[i].sub('', value)2023                                match = self._regsHex[i].search(value)2024                            break2025                value = "'" + ret + "'"2026            #print "LoggeR: Adding %s:%s" % (PeachStr(name),PeachStr(value))2027            logger.append(param)2028            params[PeachStr(name)] = PeachStr(value)2029        code = "PeachXml_" + logger.classStr + '(params)'2030        pub = eval(code)2031        pub.domLogger = logger2032        return pub2033    def HandleStateMachine(self, node, parent):2034        if node.get("name") is None:2035            raise PeachException("Parser: StateMachine missing name attribute")2036        if node.get('initialState') is None:2037            raise PeachException("Parser: StateMachine missing initialState attribute")2038        stateMachine = StateMachine(self._getAttribute(node, "name"), parent)2039        stateMachine.initialState = self._getAttribute(node, 'initialState')2040        stateMachine.onLoad = self._getAttribute(node, 'onLoad')2041        for child in node.iterchildren():2042            child_nodeName = split_ns(child.tag)[1]2043            if child_nodeName == 'State':2044                state = self.HandleState(child, stateMachine)2045                stateMachine.append(state)2046            else:2047                raise PeachException("Parser: StateMachine has unknown child [%s]" % PeachStr(child_nodeName))2048        return stateMachine2049    def HandleState(self, node, parent):2050        if node.get("name") is None:2051            raise PeachException("Parser: State missing name attribute")2052        state = State(self._getAttribute(node, 'name'), parent)2053        state.onEnter = self._getAttribute(node, 'onEnter')2054        state.onExit = self._getAttribute(node, 'onExit')2055        foundAction = False2056        for child in node.iterchildren():2057            child_nodeName = split_ns(child.tag)[1]2058            if child_nodeName == 'Action':2059                action = self.HandleAction(child, state)2060                if action.name in state:2061                    raise PeachException("Found duplicate Action name [%s]!" % action.name)2062                state.append(action)2063                foundAction = True2064            elif child_nodeName == 'Choice':2065                choice = self.HandleStateChoice(child, state)2066                state.append(choice)2067            else:2068                raise PeachException("Parser: State has unknown child [%s]" % PeachStr(child_nodeName))2069        if not foundAction:2070            raise PeachException("State [%s] has no actions" % state.name)2071        return state2072    def HandleStateChoice(self, node, parent):2073        choice = StateChoice(parent)2074        for child in node.iterchildren():2075            choice.append(self.HandleStateChoiceAction(child, node))2076        return choice2077    def HandleStateChoiceAction(self, node, parent):2078        if node.get("ref") is None:2079            raise PeachException("Parser: State::Choice::Action missing ref attribute")2080        if node.get("type") is None:2081            raise PeachException("Parser: State::Choice::Action missing type attribute")2082        ref = self._getAttribute(node, "ref")2083        type = self._getAttribute(node, "type")2084        return StateChoiceAction(ref, type, parent)2085    def HandleAction(self, node, parent):2086        if node.get("type") is None:2087            raise PeachException("Parser: Action missing 'type' attribute")2088        action = Action(self._getAttribute(node, 'name'), parent)2089        action.type = self._getAttribute(node, 'type')2090        if not action.type in ['input', 'output', 'call', 'setprop', 'getprop', 'changeState',2091                               'slurp', 'connect', 'close', 'accept', 'start', 'stop', 'wait', 'open']:2092            raise PeachException("Parser: Action type attribute is not valid [%s]." % action.type)2093        action.onStart = self._getAttribute(node, 'onStart')2094        action.onComplete = self._getAttribute(node, 'onComplete')2095        action.when = self._getAttribute(node, 'when')2096        action.ref = self._getAttribute(node, 'ref')2097        action.setXpath = self._getAttribute(node, 'setXpath')2098        action.valueXpath = self._getAttribute(node, 'valueXpath')2099        action.valueLiteral = self._getAttribute(node, 'value')2100        action.method = self._getAttribute(node, 'method')2101        action.property = self._getAttribute(node, 'property')2102        action.publisher = self._getAttribute(node, 'publisher')2103        # Quick hack to get open support.  open and connect are same.2104        if action.type == 'open':2105            action.type = 'connect'2106        if (action.setXpath or action.valueXpath or action.valueLiteral) and (2107            action.type != 'slurp' and action.type != 'wait'):2108            raise PeachException("Parser: Invalid attribute for Action were type != 'slurp'")2109        if action.method is not None and action.type != 'call':2110            raise PeachException("Parser: Method attribute on an Action only available when type is 'call'.")2111        if action.property is not None and not action.type in ['setprop', 'getprop']:2112            raise PeachException(2113                "Parser: Property attribute on an Action only available when type is 'setprop' or 'getprop'.")2114        for child in node.iterchildren():2115            child_nodeName = split_ns(child.tag)[1]2116            if child_nodeName == 'Param':2117                if not action.type in ['call', 'setprop', 'getprop']:2118                    raise PeachException("Parser: Param is an invalid child of Action for this Action type")2119                param = self.HandleActionParam(child, action)2120                if param.name in action:2121                    raise PeachException(2122                        "Error, duplicate Param name [%s] found in Action [%s]." % (param.name, action.name))2123                action.append(param)2124            elif child_nodeName == 'Template' or child_nodeName == 'DataModel':2125                if action.type not in ['input', 'output', 'getprop']:2126                    raise PeachException("Parser: DataModel is an invalid child of Action for this Action type")2127                #if child.get('ref') is None:2128                #	raise PeachException("Parser: When DataModel is a child of Action it must have the ref attribute.")2129                if action.template is not None:2130                    raise PeachException("Error, action [%s] already has a DataModel specified." % action.name)2131                obj = self.HandleTemplate(child, action)2132                action.template = obj2133                action.append(obj)2134            elif child_nodeName == 'Data':2135                if not (action.type == 'input' or action.type == 'output'):2136                    raise PeachException("Parser: Data is an invalid child of Action for this Action type")2137                if action.data is not None:2138                    raise PeachException("Error, action [%s] already has a Data element specified." % action.name)2139                data = self.HandleData(child, action)2140                action.data = data2141            elif child_nodeName == 'Result':2142                if not action.type in ['call']:2143                    raise PeachException("Parser: Result is an invalid child of Action of type 'call'.")2144                result = self.HandleActionResult(child, action)2145                if result.name in action:2146                    raise PeachException(2147                        "Error, duplicate Result name [%s] found in Action [%s]." % (param.name, action.name))2148                action.append(result)2149            else:2150                raise PeachException("Parser: State has unknown child [%s]" % PeachStr(child_nodeName))2151        if action.template is not None and action.data is not None:2152            cracker = DataCracker(action.getRoot())2153            cracker.optmizeModelForCracking(action.template)2154            # Somehow data not getting parent.  Force setting2155            action.data.parent = action2156            action.template.setDefaults(action.data, self.dontCrack, True)2157        # Verify action has a DataModel if needed2158        if action.type in ['input', 'output']:2159            if action.template is None:2160                raise PeachException("Parser: Action [%s] of type [%s] must have a DataModel child element." % (2161                    action.name, action.type))2162        # Verify that setprop has a parameter2163        if action.type == 'setprop':2164            foundActionParam = False2165            for c in action:2166                if isinstance(c, ActionParam):2167                    foundActionParam = True2168            if not foundActionParam:2169                raise PeachException(2170                    "Parser: Action [%s] of type [%s] must have a Param child element." % (action.name, action.type))2171        return action2172    def HandleActionParam(self, node, parent):2173        if node.get("type") is None:2174            raise PeachException("Parser: ActionParam missing required type attribute")2175        param = ActionParam(self._getAttribute(node, 'name'), parent)2176        param.type = self._getAttribute(node, 'type')2177        if not param.type in ['in', 'out', 'inout', 'return']:2178            raise PeachException(2179                "Parser: ActionParam type attribute is not valid [%s].  Must be one of: in, out, or inout" % param.type)2180        for child in node.iterchildren():2181            child_nodeName = split_ns(child.tag)[1]2182            if child_nodeName == 'Template' or child_nodeName == 'DataModel':2183                #if child.get('ref') is None:2184                #	raise PeachException("Parser: When Template is a child of ActionParam it must have the ref attribute.")2185                obj = self.HandleTemplate(child, param)2186                param.template = obj2187                param.append(obj)2188            elif child_nodeName == 'Data':2189                if not (param.type == 'in' or param.type == 'inout'):2190                    raise PeachException(2191                        "Parser: Data is an invalid child of ActionParam for this type [%s]" % param.type)2192                data = self.HandleData(child, param)2193                data.parent = param2194                param.data = data2195            else:2196                raise PeachException("Parser: ActionParam has unknown child [%s]" % PeachStr(child_nodeName))2197        if param.template is not None and param.data is not None:2198            cracker = DataCracker(param.template.getRoot())2199            cracker.optmizeModelForCracking(param.template)2200            param.template.setDefaults(param.data, self.dontCrack, True)2201        # Verify param has data model2202        if param.template is None:2203            raise PeachException("Parser: Action Param must have DataModel as child element.")2204        return param2205    def HandleActionResult(self, node, parent):2206        result = ActionResult(self._getAttribute(node, 'name'), parent)2207        for child in node.iterchildren():2208            child_nodeName = split_ns(child.tag)[1]2209            if child_nodeName == 'Template' or child_nodeName == 'DataModel':2210                if child.get('ref') is None:2211                    raise PeachException(2212                        "Parser: When Template is a child of ActionParam it must have the ref attribute.")2213                obj = self.HandleTemplate(child, result)2214                result.template = obj2215                result.append(obj)2216            else:2217                raise PeachException("Parser: Action Result has unknown child [%s]" % PeachStr(child_nodeName))2218        # Verify param has data model2219        if result.template is None:2220            raise PeachException("Parser: Action Result must have DataModel as child element.")2221        return result2222    def _HandleValueType(self, value, valueType):2223        """2224        Handle types: string, literal, and hex2225        """2226        if not value or not valueType:2227            return None2228        if valueType == 'literal':2229            return PeachStr(eval(value))2230        return PeachStr(value)2231    def _HandleValueTypeString(self, value, valueType):2232        """2233        Handle types: string, literal, and hex2234        """2235        if not value or not valueType:2236            return None2237        if valueType == 'literal':2238            return eval(value)2239        return value2240    def HandleParam(self, node, parent):2241        param = Param(parent)2242        if node.get("name") is None:2243            raise PeachException(2244                "Parser: Param element missing name attribute.  Parent is [{}]".format(split_ns(node.getparent().tag)[1]))2245        if node.get("value") is None:2246            raise PeachException("Parser: Param element missing value attribute.  Name is [{}].  Parent is [{}]".format(node.get("name"), split_ns(node.getparent().tag)[1]))2247        if node.get("valueType") is None:2248            valueType = "string"2249        else:2250            valueType = self._getAttribute(node, "valueType")2251        name = self._getAttribute(node, "name")2252        value = self._getAttribute(node, "value")2253        if valueType == 'string':2254            # create a literal out of a string value2255            try:2256                value = "'''" + value + "'''"2257            except TypeError:2258                raise PeachException("Parser: Failed converting param value to string.  Name is [{}].  Value is [{}].".format(name, value))2259        elif valueType == 'hex':2260            ret = ''2261            valueLen = len(value) + 12262            while valueLen > len(value):2263                valueLen = len(value)2264                for i in range(len(self._regsHex)):2265                    match = self._regsHex[i].search(value)2266                    if match is not None:2267                        while match is not None:2268                            ret += '\\x' + match.group(2)2269                            value = self._regsHex[i].sub('', value)2270                            match = self._regsHex[i].search(value)2271                        break2272            value = "'" + ret + "'"2273        param.name = name2274        param.defaultValue = PeachStr(value)2275        param.valueType = valueType2276        return param2277    def HandlePythonPath(self, node, parent):2278        if node.get('path') is None:2279            raise PeachException("PythonPath element did not have a path attribute!")2280        p = PythonPath()2281        p.name = self._getAttribute(node, 'path')2282        return p2283    def HandleImport(self, node, parent):2284        # Import module2285        if node.get('import') is None:2286            raise PeachException("HandleImport: Import element did not have import attribute!")2287        i = Element()2288        i.elementType = 'import'2289        i.importStr = self._getAttribute(node, 'import')2290        if node.get('from') is not None:2291            i.fromStr = self._getAttribute(node, 'from')2292        else:2293            i.fromStr = None2294        return i2295    def HandleHint(self, node, parent):2296        if node.get('name') is None or node.get('value') is None:2297            raise PeachException("Error: Found Hint element that didn't have both name and value attributes.")2298        hint = Hint(self._getAttribute(node, 'name'), parent)2299        hint.value = self._getAttribute(node, 'value')2300        parent.hints.append(hint)2301        return hint...Config.py
Source:Config.py  
...31        for config in configs:32            itemList = config.getElementsByTagName('add')33            for item in itemList:34                node = item.parentNode.nodeName35                key = _getAttribute(item, 'key')36                value = _getAttribute(item, 'value')37                if node in self.__CONFIG_MAP:38                    self.__CONFIG_MAP[node][key] = value39                else:40                    self.__CONFIG_MAP[node] = {}41                    self.__CONFIG_MAP[node][key] = value42    def GetSetting(self, group, key):43        ret = None44        while True:45            if group not in self.__CONFIG_MAP:46                break47            if key not in self.__CONFIG_MAP[group]:48                break49            ret = copy.copy(self.__CONFIG_MAP[group][key])50            break51        return ret52class __ParserRouter__(metaclass=Common.__Singleton__):53    """54    è§£ææ¨¡åå
³ç³»é
ç½®ï¼åå¨å¨ DATA/CONFIG ä¸ç ROUTER.XML æä»¶å½ä¸ï¼55    模åå
³ç³»å¯¹åºè·¯ç±å
³ç³»ï¼æ¯ä¸ªé
ç½®é½å¯¹åºååºç模åæä»¶ï¼æ°æ®æ¨¡åå对象56    """57    def __init__(self):58        self.__CONFIG_FILE = 'router.xml'59        self.__CONFIG_MAP = {}60        # å建å®ä¾æ¶åå§åé
ç½®61        self.__Parser()62    def __Parser(self):63        fullPath = Common.GetConfigPath() + self.__CONFIG_FILE64        # 使ç¨minidomè§£æå¨æå¼ XML ææ¡£65        DOMTree = xml.dom.minidom.parse(fullPath)66        root = DOMTree.documentElement67        # å¨éåä¸è·åææé
ç½®68        configs = root.getElementsByTagName('configuration')[0]69        # éåé
置并读åååå¨å
容70        itemList = configs.getElementsByTagName('add')71        for item in itemList:72            module = _getAttribute(item, 'module')73            handler = _getAttribute(item, 'handler')74            auth = _getAttribute(item, 'auth')75            encrypt = _getAttribute(item, 'encrypt')76            ver = _getAttribute(item, 'version')77            datatype = _getAttribute(item, 'datatype')78            resultype = _getAttribute(item, 'resultype')79            if ver not in self.__CONFIG_MAP:80                self.__CONFIG_MAP[ver] = {}81            if module not in self.__CONFIG_MAP[ver]:82                self.__CONFIG_MAP[ver][module] = {}83            if handler not in self.__CONFIG_MAP[ver][module]:84                self.__CONFIG_MAP[ver][module][handler] = {}85            self.__CONFIG_MAP[ver][module][handler]['version'] = ver86            self.__CONFIG_MAP[ver][module][handler]['auth'] = auth87            self.__CONFIG_MAP[ver][module][handler]['encrypt'] = encrypt88            self.__CONFIG_MAP[ver][module][handler]['datatype'] = datatype89            self.__CONFIG_MAP[ver][module][handler]['resultype'] = resultype90    def GetModuleByName(self, ver, module):91        if ver in self.__CONFIG_MAP:92            if module in self.__CONFIG_MAP[ver]:93                return copy.copy(self.__CONFIG_MAP[ver][module])94            else:95                return None96        else:97            return None98    def GetRouterByName(self, ver, module, handler):99        ret = None100        while True:101            if ver not in self.__CONFIG_MAP:102                break103            if module not in self.__CONFIG_MAP[ver]:104                break105            if handler not in self.__CONFIG_MAP[ver][module]:106                break107            ret = copy.copy(self.__CONFIG_MAP[ver][module][handler])108            break109        return ret110    def GetAllModule(self):111        return copy.copy(self.__CONFIG_MAP)112class __ParserModel__(metaclass=Common.__Singleton__):113    """114    è§£ææ°æ®æ¨¡åé
ç½®æä»¶ï¼æ¯ä¸ªæ¨¡åé½å°æ¯æ ¼å¼å为对象ï¼115    模ååæ¡æ¶æ°æ®äº¤äºåªè½éè¿æ°æ®æ¨¡å对象116    """117    def __init__(self):118        self.__CONFIG_FILE = 'model.xml'119        self.__CONFIG_MAP = {}120        self.__Parser()121    def __Parser(self):122        fullPath = Common.GetConfigPath() + self.__CONFIG_FILE123        # 使ç¨minidomè§£æå¨æå¼ XML ææ¡£124        DOMTree = xml.dom.minidom.parse(fullPath)125        root = DOMTree.documentElement126        # å¨éåä¸è·åææé
ç½®127        configs = root.getElementsByTagName('models')[0]128        itmeList = configs.getElementsByTagName('add')129        for item in itmeList:130            # æ ¹æ®æ°æ®æ¨¡åå称建ç«ååæ°ç对åºå
³ç³»131            modelName = _getAttribute(item, 'name')132            params = item.getElementsByTagName('parameter')133            pdic = {}134            for param in params:135                pname = _getAttribute(param, 'name')136                pdic[pname] = {}137                pdic[pname]['type'] = _getAttribute(param, 'type')138                pdic[pname]['value'] = _getAttribute(param, 'value')139                pdic[pname]['isempty'] = _getAttribute(param, 'isempty')140                pdic[pname]['extype'] = _getAttribute(param, 'extype')141                pdic[pname]['description'] = _getAttribute(param, 'description')142            self.__CONFIG_MAP[modelName] = pdic143    def GetModelByName(self, name):144        if name in self.__CONFIG_MAP:145            return copy.copy(self.__CONFIG_MAP[name])146        else:147            return None148    def HasModel(self, name):149        return name in self.__CONFIG_MAP150class __ParserSQL__(metaclass=Common.__Singleton__):151    """152    è§£ææ°æ®åºIOé
ç½®ï¼ååç±»ï¼æ¯ä¸ªSQLè¯å¥ä¸ºåä½ï¼æ¯ä¸ªåæ°éè¦æ£æ¥æ°æ®ç±»å153    """154    def __init__(self):155        self.__CONFIG_FILE = 'sql.xml'156        self.__CONFIG_SELECT_MAP = {}157        self.__CONFIG_UPDATE_MAP = {}158        self.__CONFIG_INSERT_MAP = {}159        self.__CONFIG_DELETE_MAP = {}160        self.__Parser()161    def __Parser(self):162        fullPath = Common.GetConfigPath() + self.__CONFIG_FILE163        # 使ç¨minidomè§£æå¨æå¼ XML ææ¡£164        DOMTree = xml.dom.minidom.parse(fullPath)165        root = DOMTree.documentElement166        # å¨éåä¸è·åææé
ç½®167        configs = root.getElementsByTagName('sqls')[0]168        selects = configs.getElementsByTagName('select')[0]169        selects = selects.getElementsByTagName('add')170        # è·åææ select è¯å¥171        for item in selects:172            name = _getAttribute(item, 'name')173            content = _getAttribute(item, 'content')174            description = _getAttribute(item, 'description')175            params = item.getElementsByTagName('parameter')176            pdic = {}177            for param in params:178                pname = _getAttribute(param, 'name')179                pdic[pname] = {}180                pdic[pname]['type'] = _getAttribute(param, 'type')181                pdic[pname]['value'] = _getAttribute(param, 'value')182            self.__CONFIG_SELECT_MAP[name] = {}183            self.__CONFIG_SELECT_MAP[name]['content'] = content184            self.__CONFIG_SELECT_MAP[name]['params'] = pdic185            self.__CONFIG_SELECT_MAP[name]['description'] = description186        updates = configs.getElementsByTagName('update')[0]187        updates = updates.getElementsByTagName('add')188        # è·åææ UPDATE è¯å¥189        for item in updates:190            name = _getAttribute(item, 'name')191            content = _getAttribute(item, 'content')192            description = _getAttribute(item, 'description')193            params = item.getElementsByTagName('parameter')194            pdic = {}195            for param in params:196                pname = _getAttribute(param, 'name')197                pdic[pname] = {}198                pdic[pname]['type'] = _getAttribute(param, 'type')199                pdic[pname]['value'] = _getAttribute(param, 'value')200            self.__CONFIG_UPDATE_MAP[name] = {}201            self.__CONFIG_UPDATE_MAP[name]['content'] = content202            self.__CONFIG_UPDATE_MAP[name]['params'] = pdic203            self.__CONFIG_UPDATE_MAP[name]['description'] = description204        inserts = configs.getElementsByTagName('insert')[0]205        inserts = inserts.getElementsByTagName('add')206        # è·åææ INSERT è¯å¥207        for item in inserts:208            name = _getAttribute(item, 'name')209            content = _getAttribute(item, 'content')210            description = _getAttribute(item, 'description')211            params = item.getElementsByTagName('parameter')212            pdic = {}213            for param in params:214                pname = _getAttribute(param, 'name')215                pdic[pname] = {}216                pdic[pname]['type'] = _getAttribute(param, 'type')217                pdic[pname]['value'] = _getAttribute(param, 'value')218            self.__CONFIG_INSERT_MAP[name] = {}219            self.__CONFIG_INSERT_MAP[name]['content'] = content220            self.__CONFIG_INSERT_MAP[name]['params'] = pdic221            self.__CONFIG_INSERT_MAP[name]['description'] = description222        deletes = configs.getElementsByTagName('delete')[0]223        deletes = deletes.getElementsByTagName('add')224        # è·åææ DELETE è¯å¥225        for item in deletes:226            name = _getAttribute(item, 'name')227            content = _getAttribute(item, 'content')228            description = _getAttribute(item, 'description')229            params = item.getElementsByTagName('parameter')230            pdic = {}231            for param in params:232                pname = _getAttribute(param, 'name')233                pdic[pname] = {}234                pdic[pname]['type'] = _getAttribute(param, 'type')235                pdic[pname]['value'] = _getAttribute(param, 'value')236            self.__CONFIG_DELETE_MAP[name] = {}237            self.__CONFIG_DELETE_MAP[name]['content'] = content238            self.__CONFIG_DELETE_MAP[name]['params'] = pdic239            self.__CONFIG_DELETE_MAP[name]['description'] = description240    def GetSelectSQLByName(self, name):241        """è·å SELECT é
ç½® SQL è¯å¥"""242        if name in self.__CONFIG_SELECT_MAP:243            return copy.copy(self.__CONFIG_SELECT_MAP[name]['content'])244        else:245            return None246    def GetSelectParamByName(self, name):247        """è·å SELECT é
ç½® SQL åæ°"""248        if name in self.__CONFIG_SELECT_MAP:249            return copy.copy(self.__CONFIG_SELECT_MAP[name]['params'])250        else:251            return None252    def GetInsertSQLByName(self, name):253        if name in self.__CONFIG_INSERT_MAP:254            return copy.copy(self.__CONFIG_INSERT_MAP[name]['content'])255        else:256            return None257    def GetInsertParamByName(self, name):258        if name in self.__CONFIG_INSERT_MAP:259            return copy.copy(self.__CONFIG_INSERT_MAP[name]['params'])260        else:261            return None262    def GetUpdateSQLByName(self, name):263        if name in self.__CONFIG_UPDATE_MAP:264            return copy.copy(self.__CONFIG_UPDATE_MAP[name]['content'])265        else:266            return None267    def GetUpdateParamByName(self, name):268        if name in self.__CONFIG_UPDATE_MAP:269            return copy.copy(self.__CONFIG_UPDATE_MAP[name]['params'])270        else:271            return None272    def GetDeleteSQLByName(self, name):273        if name in self.__CONFIG_DELETE_MAP:274            return copy.copy(self.__CONFIG_DELETE_MAP[name]['content'])275        else:276            return None277    def GetDeleteParamByName(self, name):278        if name in self.__CONFIG_DELETE_MAP:279            return copy.copy(self.__CONFIG_DELETE_MAP[name]['params'])280        else:281            return None282class __ParserAppConfig__(metaclass=Common.__Singleton__):283    """284    è§£æ DATA/CONFIG ç®å½ä¸ç APPCONFIG.XML æä»¶ï¼285    å°è¯¥ XML æ ¼å¼å为åå
¸ï¼åæ¾å¨åä¾å¯¹è±¡æåä¸ã286    """287    def __init__(self):288        self.__CONFIG_FILE = 'appconfig.xml'289        self.__CONFIG_MAP = {}290        self.__Parser()291    def __Parser(self):292        fullPath = Common.GetConfigPath() + self.__CONFIG_FILE293        # 使ç¨minidomè§£æå¨æå¼ XML ææ¡£294        DOMTree = xml.dom.minidom.parse(fullPath)295        root = DOMTree.documentElement296        # å¨éåä¸è·åææé
ç½®297        configs = root.getElementsByTagName('configuration')298        # éåé
置并读åååå¨å
容299        for config in configs:300            itemList = config.getElementsByTagName('add')301            for item in itemList:302                node = item.parentNode.nodeName303                key = _getAttribute(item, 'key')304                value = _getAttribute(item, 'value')305                if node in self.__CONFIG_MAP:306                    self.__CONFIG_MAP[node][key] = value307                else:308                    self.__CONFIG_MAP[node] = {}309                    self.__CONFIG_MAP[node][key] = value310    def GetSetting(self, group, key):311        ret = None312        while True:313            if group not in self.__CONFIG_MAP:314                break315            if key not in self.__CONFIG_MAP[group]:316                break317            ret = copy.copy(self.__CONFIG_MAP[group][key])318            break319        return ret320class __ParserCode__(metaclass=Common.__Singleton__):321    """è§£æ DATA/CONFIG ç®å½ä¸ç ERROR.XML æä»¶"""322    def __init__(self):323        self.__CONFIG_FILE = 'error.xml'324        self.__CONFIG_MAP = {}325        self.__Parser()326    def __Parser(self):327        fullPath = Common.GetConfigPath() + self.__CONFIG_FILE328        # 使ç¨minidomè§£æå¨æå¼ XML ææ¡£329        DOMTree = xml.dom.minidom.parse(fullPath)330        root = DOMTree.documentElement331        # å¨éåä¸è·åææé
ç½®332        retCodes = root.getElementsByTagName('retcode')[0]333        # éåé
置并读å RETCODE å
容334        itemList = retCodes.getElementsByTagName('add')335        for item in itemList:336            node = item.parentNode.nodeName337            key = _getAttribute(item, 'name')338            value = _getAttribute(item, 'value')339            if node in self.__CONFIG_MAP:340                self.__CONFIG_MAP[node][key] = value341            else:342                self.__CONFIG_MAP[node] = {}343                self.__CONFIG_MAP[node][key] = value344        # å¨éåä¸è·åææé
ç½®345        apiCodes = root.getElementsByTagName('apicode')[0]346        itemList = apiCodes.getElementsByTagName('add')347        for item in itemList:348            node = item.parentNode.nodeName349            key = _getAttribute(item, 'name')350            value = _getAttribute(item, 'value')351            if node in self.__CONFIG_MAP:352                self.__CONFIG_MAP[node][key] = value353            else:354                self.__CONFIG_MAP[node] = {}355                self.__CONFIG_MAP[node][key] = value356    def GetCodeById(self, c_type, c_id):357        """æ ¹æ®ID读å代ç è¯´æ"""358        ret = None359        while True:360            if c_type not in self.__CONFIG_MAP:361                break362            if c_id not in self.__CONFIG_MAP[c_type]:363                break364            ret = copy.copy(self.__CONFIG_MAP[c_type][c_id])365            break366        return ret367def GetRouterByName(version, module, handler):368    """è·å模å对åºç Handler ä¿¡æ¯"""369    PR = __ParserRouter__()370    return PR.GetRouterByName(version, module, handler)371def GetAllModule():372    """è·åæææ¨¡åä¿¡æ¯"""373    PR = __ParserRouter__()374    return PR.GetAllModule()375def GetModelByName(name):376    """便®åç§°è·åæ°æ®ç±»å"""377    PM = __ParserModel__()378    return PM.GetModelByName(name)379def GetSelectSQLByName(name):380    """è·å SELECT é
ç½® SQL è¯å¥"""381    PS = __ParserSQL__()382    return PS.GetSelectSQLByName(name)383def GetSelectParamByName(name):384    """è·å SELECT é
ç½® SQL åæ°"""385    PS = __ParserSQL__()386    return PS.GetSelectParamByName(name)387def GetInsertSQLByName(name):388    """è·å Insert é
ç½® SQL è¯å¥"""389    PS = __ParserSQL__()390    return PS.GetInsertSQLByName(name)391def GetInsertParamByName(name):392    """è·å Insert é
ç½® SQL åæ°"""393    PS = __ParserSQL__()394    return PS.GetInsertParamByName(name)395def GetUpdateSQLByName(name):396    """è·å Update é
ç½® SQL è¯å¥"""397    PS = __ParserSQL__()398    return PS.GetUpdateSQLByName(name)399def GetUpdateParamByName(name):400    """è·å Update é
ç½® SQL åæ°"""401    PS = __ParserSQL__()402    return PS.GetUpdateParamByName(name)403def GetDeleteSQLByName(name):404    """è·å Delete é
ç½® SQL è¯å¥"""405    PS = __ParserSQL__()406    return PS.GetDeleteSQLByName(name)407def GetDeleteParamByName(name):408    """è·å Delete é
ç½® SQL åæ°"""409    PS = __ParserSQL__()410    return PS.GetDeleteParamByName(name)411def GetSysSetting(group, key):412    """è·ååºç¨ç¨åºé
ç½®"""413    PC = __ParserConfig__()414    return PC.GetSetting(group, key)415def GetAppConfig(group, key):416    """"""417    PC = __ParserAppConfig__()418    return PC.GetSetting(group, key)419def GetCodeById(c_type, c_id):420    """便®åç§°è·åæ°æ®ç±»å"""421    PC = __ParserCode__()422    return PC.GetCodeById(c_type, c_id)423def _getAttribute(obj, name):424    """éåè·å屿§æ¹æ³ï¼è½¬æ¢å符é"""...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
