14 from rql import RQLHelper |
14 from rql import RQLHelper |
15 |
15 |
16 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid, |
16 from cubicweb import (ETYPE_NAME_MAP, Binary, UnknownProperty, UnknownEid, |
17 ObjectNotFound, NoSelectableObject, RegistryNotFound, |
17 ObjectNotFound, NoSelectableObject, RegistryNotFound, |
18 RegistryOutOfDate) |
18 RegistryOutOfDate) |
|
19 from cubicweb.utils import dump_class |
19 from cubicweb.vregistry import VRegistry, Registry |
20 from cubicweb.vregistry import VRegistry, Registry |
20 from cubicweb.rtags import RTAGS |
21 from cubicweb.rtags import RTAGS |
21 |
22 |
22 |
23 |
23 def use_interfaces(obj): |
24 def use_interfaces(obj): |
86 |
87 |
87 |
88 |
88 class ETypeRegistry(CWRegistry): |
89 class ETypeRegistry(CWRegistry): |
89 |
90 |
90 def initialization_completed(self): |
91 def initialization_completed(self): |
|
92 """on registration completed, clear etype_class internal cache |
|
93 """ |
91 super(ETypeRegistry, self).initialization_completed() |
94 super(ETypeRegistry, self).initialization_completed() |
92 # clear etype cache if you don't want to run into deep weirdness |
95 # clear etype cache if you don't want to run into deep weirdness |
93 clear_cache(self, 'etype_class') |
96 clear_cache(self, 'etype_class') |
94 |
97 |
95 def register(self, obj, **kwargs): |
98 def register(self, obj, **kwargs): |
102 super(ETypeRegistry, self).register(obj, **kwargs) |
105 super(ETypeRegistry, self).register(obj, **kwargs) |
103 |
106 |
104 @cached |
107 @cached |
105 def etype_class(self, etype): |
108 def etype_class(self, etype): |
106 """return an entity class for the given entity type. |
109 """return an entity class for the given entity type. |
107 Try to find out a specific class for this kind of entity or |
110 |
108 default to a dump of the class registered for 'Any' |
111 Try to find out a specific class for this kind of entity or default to a |
|
112 dump of the nearest parent class (in yams inheritance) registered. |
|
113 |
|
114 Fall back to 'Any' if not yams parent class found. |
109 """ |
115 """ |
110 etype = str(etype) |
116 etype = str(etype) |
111 if etype == 'Any': |
117 if etype == 'Any': |
112 return self.select('Any', 'Any') |
118 return self.select('Any', 'Any') |
113 eschema = self.schema.eschema(etype) |
119 eschema = self.schema.eschema(etype) |
114 baseschemas = [eschema] + eschema.ancestors() |
120 baseschemas = [eschema] + eschema.ancestors() |
115 # browse ancestors from most specific to most generic and |
121 # browse ancestors from most specific to most generic and try to find an |
116 # try to find an associated custom entity class |
122 # associated custom entity class |
117 for baseschema in baseschemas: |
123 for baseschema in baseschemas: |
118 try: |
124 try: |
119 btype = ETYPE_NAME_MAP[baseschema] |
125 btype = ETYPE_NAME_MAP[baseschema] |
120 except KeyError: |
126 except KeyError: |
121 btype = str(baseschema) |
127 btype = str(baseschema) |
122 try: |
128 try: |
123 cls = self.select(btype, etype) |
129 objects = self[btype] |
|
130 assert len(objects) == 1, objects |
|
131 cls = objects[0] |
124 break |
132 break |
125 except ObjectNotFound: |
133 except ObjectNotFound: |
126 pass |
134 pass |
127 else: |
135 else: |
128 # no entity class for any of the ancestors, fallback to the default |
136 # no entity class for any of the ancestors, fallback to the default |
129 # one |
137 # one |
130 cls = self.select('Any', etype) |
138 objects = self['Any'] |
|
139 assert len(objects) == 1, objects |
|
140 cls = objects[0] |
|
141 if cls.id == etype: |
|
142 cls.__initialize__() |
|
143 return cls |
|
144 cls = dump_class(cls, etype) |
|
145 cls.id = etype |
|
146 cls.__initialize__() |
131 return cls |
147 return cls |
132 |
148 |
133 VRegistry.REGISTRY_FACTORY['etypes'] = ETypeRegistry |
149 VRegistry.REGISTRY_FACTORY['etypes'] = ETypeRegistry |
134 |
150 |
135 |
151 |