36 * ``tag_attribute`` shortcut for tag_subject_of |
36 * ``tag_attribute`` shortcut for tag_subject_of |
37 """ |
37 """ |
38 __docformat__ = "restructuredtext en" |
38 __docformat__ = "restructuredtext en" |
39 |
39 |
40 import logging |
40 import logging |
|
41 from warnings import warn |
41 |
42 |
42 from logilab.common.logging_ext import set_log_methods |
43 from logilab.common.logging_ext import set_log_methods |
43 |
44 from logilab.common.registry import RegistrableInstance, yes |
44 RTAGS = [] |
|
45 def register_rtag(rtag): |
|
46 RTAGS.append(rtag) |
|
47 |
45 |
48 def _ensure_str_key(key): |
46 def _ensure_str_key(key): |
49 return tuple(str(k) for k in key) |
47 return tuple(str(k) for k in key) |
50 |
48 |
51 class RelationTags(object): |
49 class RegistrableRtags(RegistrableInstance): |
|
50 __registry__ = 'uicfg' |
|
51 __select__ = yes() |
|
52 |
|
53 |
|
54 class RelationTags(RegistrableRtags): |
52 """a tag store for full relation definitions : |
55 """a tag store for full relation definitions : |
53 |
56 |
54 (subject type, relation type, object type, tagged) |
57 (subject type, relation type, object type, tagged) |
55 |
58 |
56 allowing to set tags using wildcard (eg '*') as subject type / object type |
59 allowing to set tags using wildcard (eg '*') as subject type / object type |
57 |
60 |
58 This class associates a single tag to each key. |
61 This class associates a single tag to each key. |
59 """ |
62 """ |
60 _allowed_values = None |
63 _allowed_values = None |
61 _initfunc = None |
64 # _init expected to be a method (introduced in 3.17), while _initfunc a |
62 def __init__(self, name=None, initfunc=None, allowed_values=None): |
65 # function given as __init__ argument and kept for bw compat |
63 self._name = name or '<unknown>' |
66 _init = _initfunc = None |
|
67 |
|
68 def __init__(self): |
64 self._tagdefs = {} |
69 self._tagdefs = {} |
65 if allowed_values is not None: |
|
66 self._allowed_values = allowed_values |
|
67 if initfunc is not None: |
|
68 self._initfunc = initfunc |
|
69 register_rtag(self) |
|
70 |
70 |
71 def __repr__(self): |
71 def __repr__(self): |
72 return '%s: %s' % (self._name, repr(self._tagdefs)) |
72 # find a way to have more infos but keep it readable |
|
73 # (in error messages in case of an ambiguity for instance) |
|
74 return '%s (%s): %s' % (id(self), self.__regid__, self.__class__) |
73 |
75 |
74 # dict compat |
76 # dict compat |
75 def __getitem__(self, key): |
77 def __getitem__(self, key): |
76 return self.get(*key) |
78 return self.get(*key) |
77 __contains__ = __getitem__ |
79 __contains__ = __getitem__ |
98 if ertype != '*' and not ertype in schema: |
100 if ertype != '*' and not ertype in schema: |
99 self.warning('removing rtag %s: %s, %s undefined in schema', |
101 self.warning('removing rtag %s: %s, %s undefined in schema', |
100 (stype, rtype, otype, tagged), value, ertype) |
102 (stype, rtype, otype, tagged), value, ertype) |
101 self.del_rtag(stype, rtype, otype, tagged) |
103 self.del_rtag(stype, rtype, otype, tagged) |
102 break |
104 break |
103 if self._initfunc is not None: |
105 if self._init is not None: |
104 self.apply(schema, self._initfunc) |
106 self.apply(schema, self._init) |
105 |
107 |
106 def apply(self, schema, func): |
108 def apply(self, schema, func): |
107 for eschema in schema.entities(): |
109 for eschema in schema.entities(): |
108 if eschema.final: |
110 if eschema.final: |
109 continue |
111 continue |
111 for tschema in tschemas: |
113 for tschema in tschemas: |
112 if role == 'subject': |
114 if role == 'subject': |
113 sschema, oschema = eschema, tschema |
115 sschema, oschema = eschema, tschema |
114 else: |
116 else: |
115 sschema, oschema = tschema, eschema |
117 sschema, oschema = tschema, eschema |
116 func(self, sschema, rschema, oschema, role) |
118 func(sschema, rschema, oschema, role) |
117 |
119 |
118 # rtag declaration api #################################################### |
120 # rtag declaration api #################################################### |
119 |
121 |
120 def tag_attribute(self, key, *args, **kwargs): |
122 def tag_attribute(self, key, *args, **kwargs): |
121 key = list(key) |
123 key = list(key) |
248 elif key[-1] == 'object' and key[0] != '*': |
250 elif key[-1] == 'object' and key[0] != '*': |
249 if isinstance(key, tuple): |
251 if isinstance(key, tuple): |
250 key = list(key) |
252 key = list(key) |
251 key[0] = '*' |
253 key[0] = '*' |
252 super(NoTargetRelationTagsDict, self).tag_relation(key, tag) |
254 super(NoTargetRelationTagsDict, self).tag_relation(key, tag) |
|
255 |
|
256 |
253 set_log_methods(RelationTags, logging.getLogger('cubicweb.rtags')) |
257 set_log_methods(RelationTags, logging.getLogger('cubicweb.rtags')) |