common/appobject.py
branchtls-sprint
changeset 631 99f5852f8604
parent 447 0e52d72104a6
child 661 4f61eb8a96b7
equal deleted inserted replaced
630:66ff0b2f7d03 631:99f5852f8604
   302         """raise an exception if the given rql is not a select query"""
   302         """raise an exception if the given rql is not a select query"""
   303         first = rql.split(' ', 1)[0].lower()
   303         first = rql.split(' ', 1)[0].lower()
   304         if first in ('insert', 'set', 'delete'):
   304         if first in ('insert', 'set', 'delete'):
   305             raise Unauthorized(self.req._('only select queries are authorized'))
   305             raise Unauthorized(self.req._('only select queries are authorized'))
   306 
   306 
   307     # .accepts handling utilities #############################################
       
   308     
       
   309     accepts = ('Any',)
       
   310 
       
   311     @classmethod
       
   312     def accept_rset(cls, req, rset, row, col):
       
   313         """apply the following rules:
       
   314         * if row is None, return the sum of values returned by the method
       
   315           for each entity's type in the result set. If any score is 0,
       
   316           return 0.
       
   317         * if row is specified, return the value returned by the method with
       
   318           the entity's type of this row
       
   319         """
       
   320         if row is None:
       
   321             score = 0
       
   322             for etype in rset.column_types(0):
       
   323                 accepted = cls.accept(req.user, etype)
       
   324                 if not accepted:
       
   325                     return 0
       
   326                 score += accepted
       
   327             return score
       
   328         return cls.accept(req.user, rset.description[row][col or 0])
       
   329         
       
   330     @classmethod
       
   331     def accept(cls, user, etype):
       
   332         """score etype, returning better score on exact match"""
       
   333         if 'Any' in cls.accepts:
       
   334             return 1
       
   335         eschema = cls.schema.eschema(etype)
       
   336         matching_types = [e.type for e in eschema.ancestors()]
       
   337         matching_types.append(etype)
       
   338         for index, basetype in enumerate(matching_types):
       
   339             if basetype in cls.accepts:
       
   340                 return 2 + index
       
   341         return 0
       
   342     
       
   343     # .rtype  handling utilities ##############################################
       
   344     
       
   345     @classmethod
       
   346     def relation_possible(cls, etype):
       
   347         """tell if a relation with etype entity is possible according to 
       
   348         mixed class'.etype, .rtype and .target attributes
       
   349 
       
   350         XXX should probably be moved out to a function
       
   351         """
       
   352         schema = cls.schema
       
   353         rtype = cls.rtype
       
   354         eschema = schema.eschema(etype)
       
   355         if hasattr(cls, 'role'):
       
   356             role = cls.role
       
   357         elif cls.target == 'subject':
       
   358             role = 'object'
       
   359         else:
       
   360             role = 'subject'
       
   361         # check if this relation is possible according to the schema
       
   362         try:
       
   363             if role == 'object':
       
   364                 rschema = eschema.object_relation(rtype)
       
   365             else:
       
   366                 rschema = eschema.subject_relation(rtype)
       
   367         except KeyError:
       
   368             return False            
       
   369         if hasattr(cls, 'etype'):
       
   370             letype = cls.etype
       
   371             try:
       
   372                 if role == 'object':
       
   373                     return etype in rschema.objects(letype)
       
   374                 else:
       
   375                     return etype in rschema.subjects(letype)
       
   376             except KeyError, ex:
       
   377                 return False
       
   378         return True
       
   379 
       
   380     
       
   381     # XXX deprecated (since 2.43) ##########################
       
   382     
       
   383     @obsolete('use req.datadir_url')
       
   384     def datadir_url(self):
       
   385         """return url of the application's data directory"""
       
   386         return self.req.datadir_url
       
   387 
       
   388     @obsolete('use req.external_resource()')
       
   389     def external_resource(self, rid, default=_MARKER):
       
   390         return self.req.external_resource(rid, default)
       
   391 
       
   392         
   307         
   393 class AppObject(AppRsetObject):
   308 class AppObject(AppRsetObject):
   394     """base class for application objects which are not selected
   309     """base class for application objects which are not selected
   395     according to a result set, only by their identifier.
   310     according to a result set, only by their identifier.
   396     
   311