root / rdfalchemy / trunk / rdfalchemy / rdfsSubject.py

Revision 139, 7.3 kB (checked in by phil, 6 months ago)

rdfalchemy fixed mysql create_engine to use optional parameters (password & port)

Line 
1#!/usr/bin/env python
2# encoding: utf-8
3"""
4rdfsSubject.py
5
6rdfsSubject is similar to rdfsSubject but includes more
7processing and *magic* based on an `RDF Schema`__
8
9__ ::http://www.w3.org/TR/rdf-schema/
10
11Created by Philip Cooper on 2008-05-14.
12Copyright (c) 2008 Openvest. All rights reserved.
13"""
14
15from rdfalchemy import  rdfSubject, RDF, RDFS, Namespace
16from descriptors import *
17from orm import mapper, allsub
18
19from weakref import WeakValueDictionary
20import re
21
22OWL = Namespace("http://www.w3.org/2002/07/owl#")
23
24_all_ = ['rdfsSubject','rdfsClass','rdfsProperty',
25         'owlObjectProperty','owlDatatypeProperty',
26         'owlSymetricProperty', 'owlTransitiveProperty',
27         'owlFunctionalProperty','owlInverseFunctionalProperty']
28
29
30re_ns_n = re.compile(r'(.*[/#])(.*)')
31
32
33class rdfsSubject(rdfSubject):
34    __weakrefs = WeakValueDictionary()
35   
36    def _splitname(self):
37        return re.match(r'(.*[/#])(.*)',self.resUri).groups()
38   
39    @classmethod
40    def ClassInstances(cls):
41        """return a generator for instances of this rdf:type
42        you can look in MyClass.rdf_type to see the predicate being used"""
43        # Start with all things of "my" type in the db
44        beenthere = set([])
45        for i in cls.db.subjects(RDF.type, cls.rdf_type):
46            if not i in beenthere:
47                yield cls(i)
48                beenthere.add(i)
49       
50        # for all subclasses of me in python do the same (recursivly)
51        pySubClasses = allsub(cls)
52        for sub in pySubClasses:
53            for i in sub.ClassInstances():
54                if not i in beenthere:
55                    yield i 
56                    beenthere.add(i)
57                   
58        # not done yet, for all db subclasses that I have not processed already...get them too
59        dbSubClasses = rdfsClass(cls.rdf_type).transitive_subClasses
60        moreSubClasses = [dbsub.resUri for dbsub in dbSubClasses 
61                                if dbsub.resUri not in [pysub.rdf_type for pysub in pySubClasses]]
62        for sub in moreSubClasses:
63            for i in cls.db.subjects(RDF.type, sub):
64                if '' and not i in beenthere:
65                    yield i
66                    beenthere.add(i)       
67       
68       
69
70class rdfsClass(rdfsSubject):
71    """rdfSbject with some RDF Schema addons
72    *Some* inferencing is implied
73    Bleading edge: be careful"""
74    rdf_type = RDFS.Class
75    comment = rdfSingle(RDFS.comment)
76    label = rdfSingle(RDFS.label)   
77    subClassOf = rdfMultiple(RDFS.subClassOf, range_type = RDFS.Class)
78   
79    @property
80    def transitive_subClassOf(self):
81        return [rdfsClass(s) for s in self.db.transitive_objects(self.resUri,RDFS.subClassOf)]
82
83    @property
84    def transitive_subClasses(self):
85        return [rdfsClass(s) for s in self.db.transitive_subjects(RDFS.subClassOf, self.resUri)]
86
87    @property
88    def properties(self):
89        # this doesn't get the rdfsProperty subclasses
90        # return list(rdfsProperty.filter_by(domain=self.resUri))
91        # TODO: why iterate all rdfsProperty subclasses
92        #       try self.db.subjects(RDFS.domain,self.resUri)
93        return [x for x in rdfsProperty.ClassInstances() if x.domain == self]
94       
95       
96   
97    def _emit_rdfSubject(self, visitedNS={}, visitedClass=set([])):
98        """Procude the text that might be used for a .py file
99        TODO: This code should probably move into the commands module since that's the only place it's used"""
100        ns,loc = self._splitname()
101        try:
102            prefix, qloc = self.db.qname(self.resUri).split(':')
103        except:
104            raise Exception("don't know how do handle a qname like %s" % self.db.qname(self.resUri))
105        prefix = prefix.upper()
106       
107        if not visitedNS:
108            src = """
109from rdfalchemy import rdfSubject, Namespace, URIRef
110from rdfalchemy.rdfsSubject import rdfsSubject
111from rdfalchemy.orm import mapper
112
113"""
114            for k,v in self.db.namespaces():
115                visitedNS[str(v)] = k.upper()
116                src += '%s = Namespace("%s")\n' % (k.upper().replace('-','_'),v)
117        else:
118            src = ""
119       
120        mySupers = []
121        for mySuper in self.subClassOf:
122            sns, sloc = mySuper._splitname()
123            if ns == sns:
124                src += mySuper._emit_rdfSubject(visitedNS=visitedNS)
125                mySupers.append( sloc.replace('-','_') )
126               
127               
128               
129        mySupers = ",".join(mySupers) or "rdfsSubject"
130        src += '\nclass %s(%s):\n'%(loc.replace('-','_'), mySupers)
131        src += '\t"""%s %s"""\n'%(self.label, self.comment)
132        src += '\trdf_type = %s["%s"]\n' % (visitedNS[ns],loc)
133           
134           
135        for p in self.properties:
136            pns, ploc = p._splitname()
137            ppy = '%s["%s"]' % (visitedNS[pns],ploc)
138            try:
139                assert  str(p.range[RDF.type].resUri).endswith('Class') # rdfs.Class and owl.Class
140                rns, rloc = rdfsSubject(p.range)._splitname()
141                range_type = ', range_type = %s["%s"]' % (visitedNS[rns],rloc)
142            except Exception, e:
143                range_type = ''
144            src += '\t%s = rdfMultiple(%s%s)\n' % (ploc.replace('-','_') ,ppy,range_type)
145           
146        # Just want this once at the end
147        src.replace("mapper()\n","")       
148        src += "mapper()\n"
149                   
150        return src
151   
152class rdfsProperty(rdfsSubject):
153    rdf_type = RDF.Property
154    domain = rdfSingle(RDFS.domain, range_type=RDFS.Class)
155    range = rdfSingle(RDFS.range)
156    subPropertyOf = rdfMultiple(RDFS.subPropertyOf)
157    default_descriptor = rdfMultiple  #
158
159#####################################################################
160# Beginings of a OWL package
161
162class owlClass(rdfsClass):
163    """rdfSbject with some RDF Schema addons
164    *Some* inferencing is implied
165    Bleading edge: be careful"""
166    rdf_type = OWL["Class"]
167    disjointWith = rdfMultiple(OWL["disjointWith"], range_type = OWL["Class"])
168    equivalentClass = rdfMultiple(OWL["equivalentClass"], range_type = OWL["Class"])
169    intersectionOf = rdfMultiple(OWL["intersectionOf"])
170    unionOf = rdfMultiple(OWL["unionOf"])
171    complementOf = rdfMultiple(OWL["complementOf"], range_type = OWL["Class"])
172
173
174########################################
175# properties       
176
177class owlFunctionalProperty(rdfsProperty):
178    rdf_type = OWL.FunctionalProperty
179    default_descriptor = rdfSingle
180
181class owlDatatypeProperty(rdfsProperty):
182    rdf_type = OWL.DatatypeProperty
183    range = rdfSingle(RDFS.range, range_type = RDFS.Class)
184    default_descriptor = rdfMultiple
185       
186########################################
187# Object properties       
188class owlObjectProperty(rdfsProperty):
189    rdf_type = OWL.ObjectProperty
190    range = rdfSingle(RDFS.range, range_type = RDFS.Class)
191    inverseOf = rdfSingle(OWL.inverseOf, range_type = OWL.ObjectProperty)
192    default_descriptor = rdfMultiple
193
194class owlInverseFunctionalProperty(owlObjectProperty):
195    rdf_type = OWL.InverseFunctionalProperty
196    default_descriptor = rdfSingle
197               
198class owlSymetricProperty(owlObjectProperty):
199    rdf_type = OWL.SymetricProperty
200    default_descriptor = rdfMultiple
201       
202class owlTransitiveProperty(owlObjectProperty):
203    rdf_type = OWL.TransitiveProperty
204    default_descriptor = owlTransitive
205   
206# this maps the return type of subClassOf back to rdfsClass
207mapper()       
Note: See TracBrowser for help on using the browser.