common/selectors.py
changeset 184 92aebc6b533c
parent 162 5012aba69e62
child 213 6842c3dee34b
equal deleted inserted replaced
183:fe4d6025f712 184:92aebc6b533c
   232       for each entity's class in the result set. If any score is 0,
   232       for each entity's class in the result set. If any score is 0,
   233       return 0.
   233       return 0.
   234     * if row is specified, return the value returned by the method with
   234     * if row is specified, return the value returned by the method with
   235       the entity's class of this row
   235       the entity's class of this row
   236     """
   236     """
       
   237     # XXX this selector can be refactored : extract the code testing
       
   238     #     for entity schema / interface compliance
   237     score = 0
   239     score = 0
   238     # check 'accepts' to give priority to more specific classes
   240     # check 'accepts' to give priority to more specific classes
   239     if row is None:
   241     if row is None:
   240         for etype in rset.column_types(col or 0):
   242         for etype in rset.column_types(col or 0):
   241             eclass = cls.vreg.etype_class(etype)
   243             eclass = cls.vreg.etype_class(etype)
   243             for iface in cls.accepts_interfaces:
   245             for iface in cls.accepts_interfaces:
   244                 escore += iface.is_implemented_by(eclass)
   246                 escore += iface.is_implemented_by(eclass)
   245             if not escore:
   247             if not escore:
   246                 return 0
   248                 return 0
   247             score += escore
   249             score += escore
   248             if eclass.id in getattr(cls, 'accepts', ()):
   250             accepts = set(getattr(cls, 'accepts', ()))
   249                 score += 2
   251             # if accepts is defined on the vobject, eclass must match
       
   252             if accepts:
       
   253                 eschema = eclass.e_schema
       
   254                 etypes = set([eschema] + eschema.ancestors())
       
   255                 if accepts & etypes:
       
   256                     score += 2
       
   257                 elif 'Any' not in accepts:
       
   258                     return 0
   250         return score + 1
   259         return score + 1
   251     etype = rset.description[row][col or 0]
   260     etype = rset.description[row][col or 0]
   252     if etype is None: # outer join
   261     if etype is None: # outer join
   253         return 0
   262         return 0
   254     eclass = cls.vreg.etype_class(etype)
   263     eclass = cls.vreg.etype_class(etype)
   255     for iface in cls.accepts_interfaces:
   264     for iface in cls.accepts_interfaces:
   256         score += iface.is_implemented_by(eclass)
   265         score += iface.is_implemented_by(eclass)
   257     if score:
   266     if score:
   258         if eclass.id in getattr(cls, 'accepts', ()):
   267         accepts = set(getattr(cls, 'accepts', ()))
   259             score += 2
   268         # if accepts is defined on the vobject, eclass must match
   260         else:
   269         if accepts:
   261             score += 1
   270             eschema = eclass.e_schema
       
   271             etypes = set([eschema] + eschema.ancestors())
       
   272             if accepts & etypes:
       
   273                 score += 1
       
   274             elif 'Any' not in accepts:
       
   275                 return 0
       
   276         score += 1
   262     return score
   277     return score
   263 
   278 
   264 @lltrace
   279 @lltrace
   265 def score_entity_selector(cls, req, rset, row=None, col=None, **kwargs):
   280 def score_entity_selector(cls, req, rset, row=None, col=None, **kwargs):
   266     if row is None:
   281     if row is None: