rtags.py
author sylvain.thenault@logilab.fr
Thu, 26 Mar 2009 20:11:37 +0100
branchtls-sprint
changeset 1152 c99ef2a2535c
parent 1148 55a8238f8f7c
child 1179 70825477c6ce
permissions -rw-r--r--
cleanup
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1152
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     1
"""relation tags store
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     2
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     3
:organization: Logilab
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     4
:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     6
"""
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
     7
__docformat__ = "restructuredtext en"
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
     8
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
     9
class RelationTags(object):
1152
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    10
    """RelationTags instances are a tag store for full relation definitions :
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    11
1152
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    12
         (subject type, relation type, object type, role)
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    13
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    14
    allowing to set tags using wildcard (eg '*') as subject type / object type
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    15
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    16
    if `use_set` is True, a set of tags is associated to each key, and you
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    17
    should use rtags / etype_rtags / add_rtag api. Otherwise, a single tag is
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    18
    associated to each key, and you should use rtag / etype_rtag / set_rtag api.
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    19
    """
c99ef2a2535c cleanup
sylvain.thenault@logilab.fr
parents: 1148
diff changeset
    20
    
1148
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    21
    def __init__(self, use_set=False):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    22
        self.use_set = use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    23
        self._tagdefs = {}
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    24
        
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    25
    def set_rtag(self, tag, role, rtype, stype='*', otype='*'):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    26
        assert not self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    27
        assert role in ('subject', 'object'), role
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    28
        self._tagdefs[(stype, rtype, otype, role)] = tag
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    29
        
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    30
    def rtag(self, role, rtype, stype='*', otype='*'):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    31
        assert not self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    32
        for key in reversed(self._get_keys(role, rtype, stype, otype)):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    33
            try:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    34
                return self._tagdefs[key]
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    35
            except KeyError:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    36
                continue
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    37
        return None
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    38
        
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    39
    def etype_rtag(self, etype, role, rtype, ttype='*'):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    40
        if role == 'subject':
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    41
            return self.rtag(role, rtype, etype, ttype)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    42
        return self.rtag(role, rtype, ttype, etype)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    43
        
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    44
    def add_rtag(self, tag, role, rtype, stype='*', otype='*'):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    45
        assert self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    46
        assert role in ('subject', 'object'), role
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    47
        rtags = self._tagdefs.setdefault((stype, rtype, otype, role), set())
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    48
        rtags.add(tag)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    49
        
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    50
    def rtags(self, role, rtype, stype='*', otype='*'):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    51
        assert self.use_set
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    52
        rtags = set()
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    53
        for key in self._get_keys(role, rtype, stype, otype):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    54
            try:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    55
                rtags.update(self._tagdefs[key])
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    56
            except KeyError:
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    57
                continue
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    58
        return rtags
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    59
        
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    60
    def etype_rtags(self, etype, role, rtype, ttype='*'):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    61
        if role == 'subject':
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    62
            return self.rtags(role, rtype, etype, ttype)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    63
        return self.rtags(role, rtype, ttype, etype)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    64
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    65
    def _get_keys(self, role, rtype, stype, otype): 
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    66
        assert role in ('subject', 'object'), role
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    67
        keys = [('*', rtype, '*', role),
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    68
                ('*', rtype, otype, role),
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    69
                (stype, rtype, '*', role),
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    70
                (stype, rtype, otype, role)]
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    71
        if stype == '*' or otype == '*':
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    72
            keys.remove(('*', rtype, '*', role))
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    73
            if stype == '*':
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    74
                keys.remove(('*', rtype, otype, role))
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    75
            if otype == '*':
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    76
                keys.remove((stype, rtype, '*', role))            
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    77
        return keys
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    78
    
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    79
    # dict compat
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    80
    def __getitem__(self, key):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    81
        if isinstance(key, basestring):
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    82
            key = (key,)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    83
        return self.rtags(*key)
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    84
55a8238f8f7c keep notion of relation tags, tough with simplier implementation and usage
sylvain.thenault@logilab.fr
parents:
diff changeset
    85
    __contains__ = __getitem__