refactoring owl view (now corresponding to tbox) and owlabox view
authorLaure Bourgois <Laure.Bourgois@logilab.fr>
Wed, 11 Feb 2009 17:41:46 +0100
changeset 585 23c2f934b669
parent 584 3ca2cbf1e2ce
child 586 09ec2839e447
refactoring owl view (now corresponding to tbox) and owlabox view
web/views/owl.py
--- a/web/views/owl.py	Wed Feb 11 15:49:17 2009 +0100
+++ b/web/views/owl.py	Wed Feb 11 17:41:46 2009 +0100
@@ -1,4 +1,4 @@
-from logilab.mtconverter import html_escape
+from logilab.mtconverter import TransformError, html_escape
 
 from cubicweb.common.view import StartupView
 from cubicweb.common.view import EntityView
@@ -11,124 +11,77 @@
                 '*': ''
                 }
 
-OWL_CARD_MAP_DATA = {'String': 'xsd:string',
-                     'Datetime': 'xsd:dateTime',
-                     'Bytes': 'xsd:byte',
-                     'Float': 'xsd:float',
-                     'Boolean': 'xsd:boolean',
-                     'Int': 'xsd:int',
-                     'Date':'xsd:date',
-                     'Time': 'xsd:time',
-                     'Password': 'xsd:byte',
-                     'Decimal' : 'xsd:decimal',
-                     'Interval': 'xsd:duration'
-                     }
+OWL_TYPE_MAP = {'String': 'xsd:string',
+                'Datetime': 'xsd:dateTime',
+                'Bytes': 'xsd:byte',
+                'Float': 'xsd:float',
+                'Boolean': 'xsd:boolean',
+                'Int': 'xsd:int',
+                'Date':'xsd:date',
+                'Time': 'xsd:time',
+                'Password': 'xsd:byte',
+                'Decimal' : 'xsd:decimal',
+                'Interval': 'xsd:duration'
+                }
 
 OWL_OPENING_ROOT = u'''<?xml version="1.0" encoding="UTF-8"?>
-        <!DOCTYPE rdf:RDF [
+<!DOCTYPE rdf:RDF [
         <!ENTITY owl "http://www.w3.org/2002/07/owl#" >
         <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
-        <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
-        <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
-        <!ENTITY %s "http://logilab.org/owl/ontologies/%s#" >
-        
-        ]>        
-        <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-            xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
-            xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
-            xmlns:owl="http://www.w3.org/2002/07/owl#"
-            xmlns="http://logilab.org/owl/ontologies/%s#"
-            xmlns:%s="http://logilab.org/owl/ontologies/%s#"
-            xmlns:base="http://logilab.org/owl/ontologies/%s">
+]>        
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
+    xmlns:owl="http://www.w3.org/2002/07/owl#"
+    xmlns="http://logilab.org/owl/ontologies/%(appid)s#"
+    xmlns:%(appid)s="http://logilab.org/owl/ontologies/%(appid)s#"
+    xmlns:base="http://logilab.org/owl/ontologies/%(appid)s">
 
-    <owl:Ontology rdf:about="">
-        <rdfs:comment>
-        %s Cubicweb OWL Ontology                           
-                                        
-        </rdfs:comment>
-   </owl:Ontology>'''
+  <owl:Ontology rdf:about="">
+    <rdfs:comment>
+    %(appid)s Cubicweb OWL Ontology                           
+    </rdfs:comment>
+  </owl:Ontology>'''
 
 OWL_CLOSING_ROOT = u'</rdf:RDF>'
 
-class OWLView(StartupView):
-    """This view export in owl format the whole cubicweb ontologie. First part is the TBOX, second part is an ABOX ligth version."""
-    id = 'owl'
-    title = _('owl (tbox+abox)')
-    templatable =False
-    content_type = 'application/xml' # 'text/xml'
+DEFAULT_SKIP_RELS = frozenset(('is', 'is_instance_of', 'identity',
+                               'owned_by', 'created_by'))
 
-    def call(self):
-        
-        skipmeta = int(self.req.form.get('skipmeta', True))
-        self.w(OWL_OPENING_ROOT % (self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name))
-        self.wview('tbox', None, writeprefix=False)
-        entities = [eschema for eschema in self.schema.entities()
-                    if not eschema.is_final()]
-        if skipmeta:
-            entities = [eschema for eschema in entities
-                        if not eschema.meta]
-        for entity in entities:
-            rql = 'Any X where X is %s'
-            rset = self.req.execute(rql% entity)
-            if rset:
-                self.wview('owlaboxlight', rset, writeprefix=False)
-        self.w(OWL_CLOSING_ROOT)
-
-class TBoxView(StartupView):
+class OWLView(StartupView):
     """This view export in owl format schema database. It is the TBOX"""
-    id = 'tbox'
-    title = _('tbox')
-    templatable =False
+    id = 'owl'
+    title = _('owl')
+    templatable = False
     content_type = 'application/xml' # 'text/xml'
 
     def call(self, writeprefix=True):
         skipmeta = int(self.req.form.get('skipmeta', True))
         if writeprefix:
-            self.w(OWL_OPENING_ROOT % (self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name) )
-              
-        self.visit_schema(display_relations=True,
-                             skiprels=('is', 'is_instance_of', 'identity',
-                                       'owned_by', 'created_by'),
-                             skipmeta=skipmeta)
+            self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
+        self.visit_schema(skipmeta=skipmeta)
         if writeprefix:
             self.w(OWL_CLOSING_ROOT)
         
-    def visit_schema(self, display_relations=0,
-                     skiprels=(), skipmeta=True):
+    def visit_schema(self, skiprels=DEFAULT_SKIP_RELS, skipmeta=True):
         """get a layout for a whole schema"""
-        
-        entities = [eschema for eschema in self.schema.entities()
-                    if not eschema.is_final()]
+        entities = sorted([eschema for eschema in self.schema.entities()
+                           if not eschema.is_final()])
         if skipmeta:
             entities = [eschema for eschema in entities
                         if not eschema.meta]
-        keys = [(eschema.type, eschema) for eschema in entities]
         self.w(u'<!-- classes definition -->')
-        for key, eschema in sorted(keys):
+        for eschema in entities:
             self.visit_entityschema(eschema, skiprels)
-        self.w(u'<!-- property definition -->')
-        self.w(u'<!-- object property -->')
-        for key, eschema in sorted(keys):
-             self.visit_property_schema(eschema, skiprels)
-        self.w(u'<!-- datatype property -->')
-        for key, eschema in sorted(keys):
-            self.visit_property_object_schema(eschema, skiprels)
-         
-    def stereotype(self, name):
-        return Span((' <<%s>>' % name,), klass='stereotype')
+            self.w(u'<!-- property definition -->')
+            self.visit_property_schema(eschema, skiprels)
+            self.w(u'<!-- datatype property -->')
+            self.visit_property_object_schema(eschema)
                        
     def visit_entityschema(self, eschema, skiprels=()):
         """get a layout for an entity OWL schema"""
-        etype = eschema.type
-        
-        if eschema.meta:
-            self.stereotype('meta')
-            self.w(u'''<owl:Class rdf:ID="%s"><rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
-                                '''%eschema, stereotype)
-        else:
-             self.w(u'''<owl:Class rdf:ID="%s"><rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
-                                '''% eschema)         
-       
+        self.w(u'<owl:Class rdf:ID="%s"><rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>'
+               % eschema)         
         self.w(u'<!-- relations -->')    
         for rschema, targetschemas, role in eschema.relation_definitions():
             if rschema.type in skiprels:
@@ -141,13 +94,15 @@
                     card = rschema.rproperty(eschema, oeschema, 'cardinality')[0]
                 else:
                     card = rschema.rproperty(oeschema, eschema, 'cardinality')[1]
-                self.w(u'''<rdfs:subClassOf>
-                              <owl:Restriction>
-                              <owl:onProperty rdf:resource="#%s"/>
-                                %s
-                              </owl:Restriction>
-                           </rdfs:subClassOf>
-                                ''' % (label, OWL_CARD_MAP[card]))
+                cardtag = OWL_CARD_MAP[card]
+                if cardtag:
+                    self.w(u'''<rdfs:subClassOf>
+ <owl:Restriction>
+  <owl:onProperty rdf:resource="#%s"/>
+  %s
+ </owl:Restriction>
+</rdfs:subClassOf>
+''' % (label, cardtag))
 
         self.w(u'<!-- attributes -->')
               
@@ -157,21 +112,17 @@
             aname = rschema.type
             if aname == 'eid':
                 continue
-            card_data = aschema.type
             self.w(u'''<rdfs:subClassOf>
-                              <owl:Restriction>
-                                 <owl:onProperty rdf:resource="#%s"/>
-                                 <rdf:type rdf:resource="&owl;FunctionalProperty"/>
-                                 </owl:Restriction>
-                        </rdfs:subClassOf>'''
-                          
+  <owl:Restriction>
+   <owl:onProperty rdf:resource="#%s"/>
+   <rdf:type rdf:resource="&owl;FunctionalProperty"/>
+  </owl:Restriction>
+</rdfs:subClassOf>'''                         
                    % aname)
         self.w(u'</owl:Class>')
     
     def visit_property_schema(self, eschema, skiprels=()):
         """get a layout for property entity OWL schema"""
-        etype = eschema.type
-
         for rschema, targetschemas, role in eschema.relation_definitions():
             if rschema.type in skiprels:
                 continue
@@ -180,78 +131,54 @@
             for oeschema in targetschemas:
                 label = rschema.type
                 self.w(u'''<owl:ObjectProperty rdf:ID="%s">
-                              <rdfs:domain rdf:resource="#%s"/>
-                              <rdfs:range rdf:resource="#%s"/>
-                           </owl:ObjectProperty>                   
-                             
-                                ''' % (label, eschema, oeschema.type ))
+ <rdfs:domain rdf:resource="#%s"/>
+ <rdfs:range rdf:resource="#%s"/>
+</owl:ObjectProperty>                                                
+''' % (label, eschema, oeschema.type))
 
-    def visit_property_object_schema(self, eschema, skiprels=()):
-               
+    def visit_property_object_schema(self, eschema):
         for rschema, aschema in eschema.attribute_definitions():
             if not (rschema.has_local_role('read') or rschema.has_perm(self.req, 'read')):
                 continue
             aname = rschema.type
             if aname == 'eid':
                 continue
-            card_data = aschema.type
             self.w(u'''<owl:DatatypeProperty rdf:ID="%s">
-                          <rdfs:domain rdf:resource="#%s"/>
-                          <rdfs:range rdf:resource="%s"/>
-                       </owl:DatatypeProperty>'''
-                   % (aname, eschema, OWL_CARD_MAP_DATA[card_data]))
-            
-class OWLABOXLightView(EntityView):
-    '''This view represents the lihgt part of the ABOX for a given entity'''
-    id = 'owlaboxlight'
-    title = _('owlaboxlight')
-    templatable =False
-    accepts = ('Any',)
-    content_type = 'application/xml' # 'text/xml'
-    
-    def call(self, writeprefix=True):
+  <rdfs:domain rdf:resource="#%s"/>
+  <rdfs:range rdf:resource="%s"/>
+</owl:DatatypeProperty>'''
+                   % (aname, eschema, OWL_TYPE_MAP[aschema.type]))
 
-        skipmeta = int(self.req.form.get('skipmeta', True))
-        if writeprefix:
-            self.w(OWL_OPENING_ROOT % (self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name))
-        for i in xrange(self.rset.rowcount):
-            self.cell_call(i, 0, skiprels=('is', 'is_instance_of', 'identity',
-                                       'owned_by', 'created_by'),
-                             skipmeta=skipmeta)
-        if writeprefix:
-            self.w(OWL_CLOSING_ROOT)
-        
-
-    def cell_call(self, row, col, skiprels=(), skipmeta=True):
-        entity = self.complete_entity(row, col)
-        eschema = entity.e_schema
-        self.w(u'<%s rdf:ID="%s">' % (eschema, entity.eid))
-        self.w(u'</%s>'% eschema)
-
-
-class OWLABOXEView(EntityView):
+            
+class OWLABOXView(EntityView):
     '''This view represents a part of the ABOX for a given entity.'''
     
     id = 'owlabox'
     title = _('owlabox')
-    templatable =False
+    templatable = False
     accepts = ('Any',)
     content_type = 'application/xml' # 'text/xml'
     
-    def call(self, writeprefix=True):
-
-        skipmeta = int(self.req.form.get('skipmeta', True))
-        if writeprefix:
-            self.w(OWL_OPENING_ROOT % (self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name, self.schema.name))
+    def call(self):
+        self.w(OWL_OPENING_ROOT % {'appid': self.schema.name})
+        self.wview('owl', None, writeprefix=False)
         for i in xrange(self.rset.rowcount):
-            self.cell_call(i, 0, skiprels=('is', 'is_instance_of', 'identity',
-                                       'owned_by', 'created_by'),
-                             skipmeta=skipmeta)
-        if writeprefix:
-            self.w(OWL_CLOSING_ROOT)
+            self.cell_call(i, 0)
+        self.w(OWL_CLOSING_ROOT)
+
+    def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS):
+        self.wview('owlaboxitem', self.rset, row=row, col=col, skiprels=skiprels)
+
         
+class OWLABOXItemView(EntityView):
+    '''This view represents a part of the ABOX for a given entity.'''
+    
+    id = 'owlaboxitem'
+    templatable = False
+    accepts = ('Any',)
+    content_type = 'application/xml' # 'text/xml'
 
-    def cell_call(self, row, col, skiprels=(), skipmeta=True):
+    def cell_call(self, row, col, skiprels=DEFAULT_SKIP_RELS):
         entity = self.complete_entity(row, col)
         eschema = entity.e_schema
         self.w(u'<%s rdf:ID="%s">' % (eschema, entity.eid))
@@ -264,9 +191,12 @@
             aname = rschema.type
             if aname == 'eid':
                 continue
-            attr = getattr(entity, aname)
-            if attr is not None:
-                self.w(u'<%s>%s</%s>' % (aname, html_escape(unicode(attr)), aname))
+            try:
+                attr = entity.printable_value(aname, format='text/plain')
+                if attr:
+                    self.w(u'<%s>%s</%s>' % (aname, html_escape(attr), aname))
+            except TransformError:
+                pass
         self.w(u'<!--relations -->')
         for rschema, targetschemas, role in eschema.relation_definitions():
             if rschema.type in skiprels: