############################################################################## # # Copyright (c) 2004-1005 Michel Pelletier # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## __rdf_description__ = '''\ ''' # For now we're going to bootstrap off of schemaweb.info, but soon # I'll have zemantic.org running a Zontology that serves up this # information to everyone else. Any = None from persistent import Persistent from persistent.dict import PersistentDict import urllib, os, xml from rdflib.URIRef import URIRef from rdflib.BNode import BNode from rdflib.Literal import Literal from rdflib.Identifier import Identifier from rdflib.constants import * from rdflib.exceptions import ParserError, Error from zemantic import Zemantic from query import Query from lib.IOZODBBackend import IOZODBBackend from interfaces import IZontology, IOntology, IZemantic from zope.interface import implements from zope.interface.verify import verifyClass from zope.app.folder.folder import Folder from resources import FileResource, DirectoryResource class Ontology(Zemantic): """ A Zemantic catalog intended to hold one ontology. with property and class discovery routines, used in Zontology containers. See Zontology class below for tests. """ implements(IOntology, IZemantic) def properties(self): # implement _v_caching of properties r = {} q = self.query(Query(Any, TYPE, PROPERTY)) for p in q: if p is not None: v, k = split_URI(p.subject) r[k] = p.subject return r def classes(self): # implement _v_caching of classes r = {} q = self.query(Query(Any, TYPE, RDFS_CLASS)) for p in q: if p is not None: v, k = split_URI(p.subject) r[k] = p.subject q = self.query(Query(Any, RDFS_SUBCLASSOF, Any)) for p in q: if p is not None: v, k = split_URI(p.subject) r[k] = p.subject return r def hasProperty(self, name): return self.properties().has_key(name) def hasClass(self, name): return self.classes().has_key(name) def __getitem__(self, attr): cls = self.classes() prs = self.properties() if cls.has_key(attr): return cls[attr] if prs.has_key(attr): return prs[attr] raise KeyError, "%s does not exist in the schema %s" % (attr, self.__name__) class Zontology(Folder): """ A utility for registering ontologies in RDF format. Each ontology is cataloged in its own internal Zemantic and can be quieried. This doctest is intended to flex everything. >>> from public import * >>> z = Zontology() >>> IZontology.providedBy(z) True >>> verifyClass(IZontology, Zontology) True >>> z.addFileOntology('dc', 'data/dc.rdf') >>> len(list(z['dc'].query(Query()))) 146 >>> z.addFileOntology('food', 'data/food.rdf') >>> len(list(z['food'].query(Query()))) 870 >>> z.addFileOntology('owl', 'data/owl.rdf') >>> len(list(z['owl'].query(Query()))) 160 >>> z.addFileOntology('rdf', 'data/rdf.rdf') >>> len(list(z['rdf'].query(Query()))) 85 >>> z.addFileOntology('sumo', 'data/sumo.rdf') >>> len(list(z['sumo'].query(Query()))) 3688 >>> z.addFileOntology('foaf', 'data/foaf.rdf') >>> len(list(z['sumo'].query(Query()))) 3688 """ implements(IZontology) __name__ = __parent__ = None def __init__(self): Folder.__init__(self) def getLabels(self): return self.keys() def addStringOntology(self, label, str): f = StringIO(str) z = Ontology() z.parse(f) self[label] = z def addWebOntology(self, label, URL): f = urllib.urlopen(URL) z = Ontology() z.parse(f) self[label] = z def addFileOntology(self, label, file, _prefix=None): f = FileResource(file, _prefix).open() z = Ontology() z.parse(f) self[label] = z def addPageTemplateFileOntology(self, label, file): f = PageTemplateFile(file) z = Ontology() z.parse(StringIO(f())) self[label] = z # from rdflib NAMESTART = u'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_' NAMECHARS = NAMESTART + u'0123456789-.' def split_URI(uri): uri = uri length = len(uri) for i in xrange(0, length): if not uri[-i-1] in NAMECHARS: for j in xrange(-1-i, length): if uri[j] in NAMESTART: ns = uri[:j] if not ns: break qn = uri[j:] return (ns, qn) break raise Error("Could not split uri: '%s'" % uri)