poco.sdk.DefaultMatcher 源代码

# coding=utf-8

import re
from .exceptions import NoSuchComparatorException

__author__ = 'lxn3032'
__all__ = ['IMatcher', 'DefaultMatcher', 'EqualizationComparator', 'RegexpComparator']


class IMatcher(object):
    def match(self, cond, node):
        """
        Test whether or not the node matches the given condition.

        Args:
            cond (:obj:`tuple`): query expression
            node (:py:class:`inherit from AbstractNode <poco.sdk.AbstractNode>`): node to be tested

        Returns:
            bool: True if matches otherwise False.
        """

        raise NotImplementedError


[文档]class EqualizationComparator(object): """ Compare two objects using the native equivalence (==) comparison operator """ def compare(self, l, r): return l == r
[文档]class RegexpComparator(object): """ Compare two objects using regular expression. Available only when the original value is string type. It always returns False if the original value or given pattern are not :obj:`str` type. """
[文档] def compare(self, origin, pattern): """ Args: origin (:obj:`str`): original string pattern (:obj:`str`): Regexp pattern string Returns: bool: True if matches otherwise False. """ if origin is None or pattern is None: return False return re.match(pattern, origin) is not None
[文档]class DefaultMatcher(IMatcher): """ Default matcher implementation for poco hierarchy traversing. Including logical query condition and predicate expression. When traversing through the hierarchy tree, matcher will apply the match method on each node of the tree. The formal definition of query condition as follows:: expr := (op0, (expr0, expr1, ...)) expr := (op1, (arg1, arg2)) - ``op0``:obj:`str` is logical operator ('or' or 'and') which has the same semantics as in python, e.g. 'or' means this expression/condition matches if any of the exprN matches - ``op1``:obj:`str` is comparator, can be one of as follows:: op1 := 'attr=' op1 := 'attr.*=' op1 := ... (other customized) - ``attr=`` corresponds to :py:class:`EqualizationComparator <poco.sdk.DefaultMatcher.EqualizationComparator>`. - ``attr.*=`` corresponds to :py:class:`RegexpComparator <poco.sdk.DefaultMatcher.RegexpComparator>`. The ``op1`` must be a string. The ``Matcher`` will help to map to ``Comparator`` object. """ def __init__(self): super(DefaultMatcher, self).__init__() self.comparators = { 'attr=': EqualizationComparator(), 'attr.*=': RegexpComparator(), }
[文档] def match(self, cond, node): """ See Also: :py:meth:`IMatcher.match <poco.sdk.DefaultMatcher.IMatcher.match>` """ op, args = cond # 条件匹配 if op == 'and': for arg in args: if not self.match(arg, node): return False return True if op == 'or': for arg in args: if self.match(arg, node): return True return False # 属性匹配 comparator = self.comparators.get(op) if comparator: attribute, value = args targetValue = node.getAttr(attribute) return comparator.compare(targetValue, value) raise NoSuchComparatorException(op, 'poco.sdk.DefaultMatcher')