web/views/owl.py
changeset 2126 a25859917ccc
parent 1977 606923dff11b
child 2186 dba8eed12a16
equal deleted inserted replaced
2123:3e1d2ab5f8c0 2126:a25859917ccc
     4 :copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     4 :copyright: 2008-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     7 """
     7 """
     8 __docformat__ = "restructuredtext en"
     8 __docformat__ = "restructuredtext en"
       
     9 _ = unicode
     9 
    10 
    10 from logilab.mtconverter import TransformError, xml_escape
    11 from logilab.mtconverter import TransformError, xml_escape
    11 
    12 
    12 from cubicweb.view import StartupView, EntityView
    13 from cubicweb.view import StartupView, EntityView
       
    14 from cubicweb.selectors import none_rset, match_view
    13 from cubicweb.web.action import Action
    15 from cubicweb.web.action import Action
    14 from cubicweb.selectors import none_rset, match_view
    16 from cubicweb.web.views import schema
    15 
       
    16 _ = unicode
       
    17 
    17 
    18 OWL_CARD_MAP = {'1': '<rdf:type rdf:resource="&owl;FunctionalProperty"/>',
    18 OWL_CARD_MAP = {'1': '<rdf:type rdf:resource="&owl;FunctionalProperty"/>',
    19                 '?': '<owl:maxCardinality rdf:datatype="&xsd;int">1</owl:maxCardinality>',
    19                 '?': '<owl:maxCardinality rdf:datatype="&xsd;int">1</owl:maxCardinality>',
    20                 '+': '<owl:minCardinality rdf:datatype="&xsd;int">1</owl:minCardinality>',
    20                 '+': '<owl:minCardinality rdf:datatype="&xsd;int">1</owl:minCardinality>',
    21                 '*': ''
    21                 '*': ''
    53     </rdfs:comment>
    53     </rdfs:comment>
    54   </owl:Ontology>'''
    54   </owl:Ontology>'''
    55 
    55 
    56 OWL_CLOSING_ROOT = u'</rdf:RDF>'
    56 OWL_CLOSING_ROOT = u'</rdf:RDF>'
    57 
    57 
    58 DEFAULT_SKIP_RELS = frozenset(('is', 'is_instance_of', 'identity',
       
    59                                'owned_by', 'created_by'))
       
    60 
    58 
    61 class OWLView(StartupView):
    59 class OWLView(StartupView):
    62     """This view export in owl format schema database. It is the TBOX"""
    60     """This view export in owl format schema database. It is the TBOX"""
    63     id = 'owl'
    61     id = 'owl'
    64     title = _('owl')
    62     title = _('owl')
    67 
    65 
    68     def call(self, writeprefix=True):
    66     def call(self, writeprefix=True):
    69         skipmeta = int(self.req.form.get('skipmeta', True))
    67         skipmeta = int(self.req.form.get('skipmeta', True))
    70         if writeprefix:
    68         if writeprefix:
    71             self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
    69             self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
    72         self.visit_schema(skipmeta=skipmeta)
    70         self.visit_schema(skiptypes=skipmeta and schema.SKIP_TYPES or ())
    73         if writeprefix:
    71         if writeprefix:
    74             self.w(OWL_CLOSING_ROOT)
    72             self.w(OWL_CLOSING_ROOT)
    75 
    73 
    76     def visit_schema(self, skiprels=DEFAULT_SKIP_RELS, skipmeta=True):
    74     def should_display_rschema(self, rschema):
       
    75         return not rschema in self.skiptypes and (
       
    76             rschema.has_local_role('read') or
       
    77             rschema.has_perm(self.req, 'read')):
       
    78 
       
    79     def visit_schema(self, skiptypes):
    77         """get a layout for a whole schema"""
    80         """get a layout for a whole schema"""
    78         entities = sorted([eschema for eschema in self.schema.entities()
    81         self.skiptypes = skiptypes
    79                            if not eschema.is_final()])
    82         entities = sorted(eschema for eschema in self.schema.entities()
    80         if skipmeta:
    83                           if not eschema.is_final() or eschema in skiptypes)
    81             entities = [eschema for eschema in entities
       
    82                         if not eschema.meta]
       
    83         self.w(u'<!-- classes definition -->')
    84         self.w(u'<!-- classes definition -->')
    84         for eschema in entities:
    85         for eschema in entities:
    85             self.visit_entityschema(eschema, skiprels)
    86             self.visit_entityschema(eschema)
    86             self.w(u'<!-- property definition -->')
    87             self.w(u'<!-- property definition -->')
    87             self.visit_property_schema(eschema, skiprels)
    88             self.visit_property_schema(eschema)
    88             self.w(u'<!-- datatype property -->')
    89             self.w(u'<!-- datatype property -->')
    89             self.visit_property_object_schema(eschema)
    90             self.visit_property_object_schema(eschema)
    90 
    91 
    91     def visit_entityschema(self, eschema, skiprels=()):
    92     def visit_entityschema(self, eschema):
    92         """get a layout for an entity OWL schema"""
    93         """get a layout for an entity OWL schema"""
    93         self.w(u'<owl:Class rdf:ID="%s">'% eschema)
    94         self.w(u'<owl:Class rdf:ID="%s">'% eschema)
    94         self.w(u'<!-- relations -->')
    95         self.w(u'<!-- relations -->')
    95         for rschema, targetschemas, role in eschema.relation_definitions():
    96         for rschema, targetschemas, role in eschema.relation_definitions():
    96             if rschema.type in skiprels:
    97             if not self.should_display_rschema(rschema):
    97                 continue
       
    98             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
       
    99                 continue
    98                 continue
   100             for oeschema in targetschemas:
    99             for oeschema in targetschemas:
   101                 label = rschema.type
       
   102                 if role == 'subject':
   100                 if role == 'subject':
   103                     card = rschema.rproperty(eschema, oeschema, 'cardinality')[0]
   101                     card = rschema.rproperty(eschema, oeschema, 'cardinality')[0]
   104                 else:
   102                 else:
   105                     card = rschema.rproperty(oeschema, eschema, 'cardinality')[1]
   103                     card = rschema.rproperty(oeschema, eschema, 'cardinality')[1]
   106                 cardtag = OWL_CARD_MAP[card]
   104                 cardtag = OWL_CARD_MAP[card]
   108                     self.w(u'''<rdfs:subClassOf>
   106                     self.w(u'''<rdfs:subClassOf>
   109  <owl:Restriction>
   107  <owl:Restriction>
   110   <owl:onProperty rdf:resource="#%s"/>
   108   <owl:onProperty rdf:resource="#%s"/>
   111   %s
   109   %s
   112  </owl:Restriction>
   110  </owl:Restriction>
   113 </rdfs:subClassOf>
   111 </rdfs:subClassOf>''' % (rschema, cardtag))
   114 ''' % (label, cardtag))
       
   115 
   112 
   116         self.w(u'<!-- attributes -->')
   113         self.w(u'<!-- attributes -->')
   117 
       
   118         for rschema, aschema in eschema.attribute_definitions():
   114         for rschema, aschema in eschema.attribute_definitions():
   119             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
   115             if not self.should_display_rschema(rschema):
   120                 continue
       
   121             aname = rschema.type
       
   122             if aname == 'eid':
       
   123                 continue
   116                 continue
   124             self.w(u'''<rdfs:subClassOf>
   117             self.w(u'''<rdfs:subClassOf>
   125   <owl:Restriction>
   118   <owl:Restriction>
   126    <owl:onProperty rdf:resource="#%s"/>
   119    <owl:onProperty rdf:resource="#%s"/>
   127    <rdf:type rdf:resource="&owl;FunctionalProperty"/>
   120    <rdf:type rdf:resource="&owl;FunctionalProperty"/>
   128   </owl:Restriction>
   121   </owl:Restriction>
   129 </rdfs:subClassOf>'''
   122 </rdfs:subClassOf>''' % rschema)
   130                    % aname)
       
   131         self.w(u'</owl:Class>')
   123         self.w(u'</owl:Class>')
   132 
   124 
   133     def visit_property_schema(self, eschema, skiprels=()):
   125     def visit_property_schema(self, eschema):
   134         """get a layout for property entity OWL schema"""
   126         """get a layout for property entity OWL schema"""
   135         for rschema, targetschemas, role in eschema.relation_definitions():
   127         for rschema, targetschemas, role in eschema.relation_definitions():
   136             if rschema.type in skiprels:
   128             if not self.should_display_rschema(rschema):
   137                 continue
       
   138             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
       
   139                 continue
   129                 continue
   140             for oeschema in targetschemas:
   130             for oeschema in targetschemas:
   141                 label = rschema.type
   131                 label = rschema.type
   142                 self.w(u'''<owl:ObjectProperty rdf:ID="%s">
   132                 self.w(u'''<owl:ObjectProperty rdf:ID="%s">
   143  <rdfs:domain rdf:resource="#%s"/>
   133  <rdfs:domain rdf:resource="#%s"/>
   144  <rdfs:range rdf:resource="#%s"/>
   134  <rdfs:range rdf:resource="#%s"/>
   145 </owl:ObjectProperty>
   135 </owl:ObjectProperty>''' % (label, eschema, oeschema.type))
   146 ''' % (label, eschema, oeschema.type))
       
   147 
   136 
   148     def visit_property_object_schema(self, eschema):
   137     def visit_property_object_schema(self, eschema):
   149         for rschema, aschema in eschema.attribute_definitions():
   138         for rschema, aschema in eschema.attribute_definitions():
   150             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
   139             if not self.should_display_rschema(rschema):
   151                 continue
       
   152             aname = rschema.type
       
   153             if aname == 'eid':
       
   154                 continue
   140                 continue
   155             self.w(u'''<owl:DatatypeProperty rdf:ID="%s">
   141             self.w(u'''<owl:DatatypeProperty rdf:ID="%s">
   156   <rdfs:domain rdf:resource="#%s"/>
   142   <rdfs:domain rdf:resource="#%s"/>
   157   <rdfs:range rdf:resource="%s"/>
   143   <rdfs:range rdf:resource="%s"/>
   158 </owl:DatatypeProperty>'''
   144 </owl:DatatypeProperty>''' % (aname, eschema, OWL_TYPE_MAP[aschema.type]))
   159                    % (aname, eschema, OWL_TYPE_MAP[aschema.type]))
       
   160 
   145 
   161 
   146 
   162 class OWLABOXView(EntityView):
   147 class OWLABOXView(EntityView):
   163     '''This view represents a part of the ABOX for a given entity.'''
   148     '''This view represents a part of the ABOX for a given entity.'''
   164 
       
   165     id = 'owlabox'
   149     id = 'owlabox'
   166     title = _('owlabox')
   150     title = _('owlabox')
   167     templatable = False
   151     templatable = False
   168     content_type = 'application/xml' # 'text/xml'
   152     content_type = 'application/xml' # 'text/xml'
   169 
   153 
   171         self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
   155         self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
   172         for i in xrange(self.rset.rowcount):
   156         for i in xrange(self.rset.rowcount):
   173             self.cell_call(i, 0)
   157             self.cell_call(i, 0)
   174         self.w(OWL_CLOSING_ROOT)
   158         self.w(OWL_CLOSING_ROOT)
   175 
   159 
   176     def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS):
   160     def cell_call(self, row, col):
   177         self.wview('owlaboxitem', self.rset, row=row, col=col, skiprels=skiprels)
   161         self.wview('owlaboxitem', self.rset, row=row, col=col)
   178 
   162 
   179 
   163 
   180 class OWLABOXItemView(EntityView):
   164 class OWLABOXItemView(EntityView):
   181     '''This view represents a part of the ABOX for a given entity.'''
   165     '''This view represents a part of the ABOX for a given entity.'''
   182     id = 'owlaboxitem'
   166     id = 'owlaboxitem'
   183     templatable = False
   167     templatable = False
   184     content_type = 'application/xml' # 'text/xml'
   168     content_type = 'application/xml' # 'text/xml'
   185 
   169 
   186     def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS):
   170     def cell_call(self, row, col):
   187         entity = self.complete_entity(row, col)
   171         entity = self.complete_entity(row, col)
   188         eschema = entity.e_schema
   172         eschema = entity.e_schema
   189         self.w(u'<%s rdf:ID="%s">' % (eschema, entity.eid))
   173         self.w(u'<%s rdf:ID="%s">' % (eschema, entity.eid))
   190         self.w(u'<!--attributes-->')
   174         self.w(u'<!--attributes-->')
   191         for rschema, aschema in eschema.attribute_definitions():
   175         for rschema, aschema in eschema.attribute_definitions():
   192             if rschema.type in skiprels:
   176             if rschema.meta:
   193                 continue
   177                 continue
   194             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
   178             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
   195                 continue
   179                 continue
   196             aname = rschema.type
   180             aname = rschema.type
   197             if aname == 'eid':
   181             if aname == 'eid':
   202                     self.w(u'<%s>%s</%s>' % (aname, xml_escape(attr), aname))
   186                     self.w(u'<%s>%s</%s>' % (aname, xml_escape(attr), aname))
   203             except TransformError:
   187             except TransformError:
   204                 pass
   188                 pass
   205         self.w(u'<!--relations -->')
   189         self.w(u'<!--relations -->')
   206         for rschema, targetschemas, role in eschema.relation_definitions():
   190         for rschema, targetschemas, role in eschema.relation_definitions():
   207             if rschema.type in skiprels:
   191             if rschema.meta:
   208                 continue
   192                 continue
   209             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
   193             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
   210                 continue
   194                 continue
   211             if role == 'object':
   195             if role == 'object':
   212                 attr = 'reverse_%s' % rschema.type
   196                 attr = 'reverse_%s' % rschema.type