4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
6 """ |
6 """ |
7 __docformat__ = "restructuredtext en" |
7 __docformat__ = "restructuredtext en" |
8 |
8 |
|
9 |
9 class RelationTags(object): |
10 class RelationTags(object): |
10 """RelationTags instances are a tag store for full relation definitions : |
11 """a tag store for full relation definitions : |
11 |
12 |
12 (subject type, relation type, object type, role) |
13 (subject type, relation type, object type, tagged) |
13 |
14 |
14 allowing to set tags using wildcard (eg '*') as subject type / object type |
15 allowing to set tags using wildcard (eg '*') as subject type / object type |
15 |
16 |
16 if `use_set` is True, a set of tags is associated to each key, and you |
17 This class associates a single tag to each key. |
17 should use rtags / etype_rtags / add_rtag api. Otherwise, a single tag is |
|
18 associated to each key, and you should use rtag / etype_rtag / set_rtag api. |
|
19 """ |
18 """ |
20 |
19 |
21 def __init__(self, use_set=False): |
20 def __init__(self): |
22 self.use_set = use_set |
|
23 self._tagdefs = {} |
21 self._tagdefs = {} |
24 |
22 |
25 def __repr__(self): |
23 def __repr__(self): |
26 return repr(self._tagdefs) |
24 return repr(self._tagdefs) |
27 |
25 |
28 def set_rtag(self, tag, rtype, role, stype='*', otype='*'): |
26 # dict compat |
29 assert not self.use_set |
27 def __getitem__(self, key): |
30 assert role in ('subject', 'object'), role |
28 return self.get(*key) |
31 self._tagdefs[(str(rtype), role, str(stype), str(otype))] = tag |
29 __contains__ = __getitem__ |
32 |
30 |
33 def del_rtag(self, rtype, role, stype='*', otype='*'): |
31 def _get_keys(self, rtype, tagged, stype, otype): |
34 assert not self.use_set |
32 assert tagged in ('subject', 'object'), tagged |
35 assert role in ('subject', 'object'), role |
33 keys = [(rtype, tagged, '*', '*'), |
36 del self._tagdefs[(str(rtype), role, str(stype), str(otype))] |
34 (rtype, tagged, '*', otype), |
|
35 (rtype, tagged, stype, '*'), |
|
36 (rtype, tagged, stype, otype)] |
|
37 if stype == '*' or otype == '*': |
|
38 keys.remove((rtype, tagged, '*', '*')) |
|
39 if stype == '*': |
|
40 keys.remove((rtype, tagged, '*', otype)) |
|
41 if otype == '*': |
|
42 keys.remove((rtype, tagged, stype, '*')) |
|
43 return keys |
37 |
44 |
38 def rtag(self, rtype, role, stype='*', otype='*'): |
45 def tag_relation(self, tag, relation, tagged): |
39 assert not self.use_set |
46 assert tagged in ('subject', 'object'), tagged |
40 for key in reversed(self._get_keys(rtype, role, stype, otype)): |
47 stype, rtype, otype = relation |
|
48 self._tagdefs[(str(rtype), tagged, str(stype), str(otype))] = tag |
|
49 |
|
50 def del_rtag(self, relation, tagged): |
|
51 assert tagged in ('subject', 'object'), tagged |
|
52 stype, rtype, otype = relation |
|
53 del self._tagdefs[(str(rtype), tagged, str(stype), str(otype))] |
|
54 |
|
55 def get(self, rtype, tagged, stype='*', otype='*'): |
|
56 for key in reversed(self._get_keys(rtype, tagged, stype, otype)): |
41 try: |
57 try: |
42 return self._tagdefs[key] |
58 return self._tagdefs[key] |
43 except KeyError: |
59 except KeyError: |
44 continue |
60 continue |
45 return None |
61 return None |
46 |
62 |
47 def etype_rtag(self, etype, rtype, role, ttype='*'): |
63 def etype_get(self, etype, rtype, tagged, ttype='*'): |
48 if role == 'subject': |
64 if tagged == 'subject': |
49 return self.rtag(rtype, role, etype, ttype) |
65 return self.get(rtype, tagged, etype, ttype) |
50 return self.rtag(rtype, role, ttype, etype) |
66 return self.get(rtype, tagged, ttype, etype) |
51 |
67 |
52 def add_rtag(self, tag, rtype, role, stype='*', otype='*'): |
68 |
53 assert self.use_set |
69 |
54 assert role in ('subject', 'object'), role |
70 class RelationTagsSet(RelationTags): |
55 rtags = self._tagdefs.setdefault((rtype, role, stype, otype), set()) |
71 """This class associates a set of tags to each key.""" |
|
72 |
|
73 def tag_relation(self, tag, relation, tagged): |
|
74 assert tagged in ('subject', 'object'), tagged |
|
75 stype, rtype, otype = relation |
|
76 rtags = self._tagdefs.setdefault((rtype, tagged, stype, otype), set()) |
56 rtags.add(tag) |
77 rtags.add(tag) |
57 |
78 |
58 def rtags(self, rtype, role, stype='*', otype='*'): |
79 def get(self, rtype, tagged, stype='*', otype='*'): |
59 assert self.use_set |
|
60 rtags = set() |
80 rtags = set() |
61 for key in self._get_keys(rtype, role, stype, otype): |
81 for key in self._get_keys(rtype, tagged, stype, otype): |
62 try: |
82 try: |
63 rtags.update(self._tagdefs[key]) |
83 rtags.update(self._tagdefs[key]) |
64 except KeyError: |
84 except KeyError: |
65 continue |
85 continue |
66 return rtags |
86 return rtags |
67 |
|
68 def etype_rtags(self, etype, rtype, role, ttype='*'): |
|
69 if role == 'subject': |
|
70 return self.rtags(rtype, role, etype, ttype) |
|
71 return self.rtags(rtype, role, ttype, etype) |
|
72 |
|
73 def _get_keys(self, rtype, role, stype, otype): |
|
74 assert role in ('subject', 'object'), role |
|
75 keys = [(rtype, role, '*', '*'), |
|
76 (rtype, role, '*', otype), |
|
77 (rtype, role, stype, '*'), |
|
78 (rtype, role, stype, otype)] |
|
79 if stype == '*' or otype == '*': |
|
80 keys.remove((rtype, role, '*', '*')) |
|
81 if stype == '*': |
|
82 keys.remove((rtype, role, '*', otype)) |
|
83 if otype == '*': |
|
84 keys.remove((rtype, role, stype, '*')) |
|
85 return keys |
|
86 |
|
87 # dict compat |
|
88 def __getitem__(self, key): |
|
89 if isinstance(key, basestring): |
|
90 key = (key,) |
|
91 return self.rtags(*key) |
|
92 |
|
93 __contains__ = __getitem__ |
|