############################################################################## # # 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__ = '''\ ''' from zope.app import zapi from types import UnicodeType, TupleType from zope.interface import implements from zope.security.proxy import removeSecurityProxy from zope.tales.tales import _valid_name, _parse_expr, NAME_RE, Undefined, CompilerError from zope.tales.interfaces import ITALESExpression, ITALESFunctionNamespace from rdflib.URIRef import URIRef from rdflib.BNode import BNode from rdflib.Literal import Literal from rdflib.Identifier import Identifier from interfaces import * from query import Query, UnionChain from result import ResultSet import sys from zope.tales.engine import Engine from zope.tales.tales import Context class ZemanticExpr(object): """\ Zemantic query expressions. A zemantic expression has the triple expression form: (,

, ) The results of each sub expression in the triple pattern are used to query the nearest zemantic catalog site utility. Sub-expressions can be any kind of TALES expression (string, nocall, not, path, python etc.) but the expression must return one of the following: None - Matches all ident string or unicode - a string or unicode identifier in N3 format. IIdentifier implementor (BNode, URIRef, Literal) - an identifier object. Inner queries can be defined by returning: 3-tuple - defines standard inner query. IQuery implementor - defines custom inner query. The actual query logic is not implemented by the expression, for that look at zemantic.query.Query. """ implements(ITALESExpression) def __init__(self, name, expr, engine): self._s = expr self._name = name self.engine = engine self.expr = self._compile(expr) def _compile(self, expression): m = _parse_expr(expression) if m: type = m.group(1) expr = expression[m.end():] else: type = "python" expr = expression try: handler = self.engine.getTypes()[type] except KeyError: raise CompilerError, ('Unrecognized expression type "%s".' % type) return handler(type, expr, self.engine) def __call__(self, econtext): c = zapi.queryUtility(IZemantic) o = zapi.queryUtility(IZontology) # eval each expression, stuffing the result in a Query object. # Query will raise an error if the argument is not proper # like. if c is not None: econtext.setLocal('zem', c) if o is not None: econtext.setLocal('zon', o) econtext.setLocal('Any', None) econtext.setLocal('URIRef', URIRef) econtext.setLocal('BNode', BNode) econtext.setLocal('Literal', Literal) q = self.expr(econtext) if type(q) is TupleType: if len(q) != 3: raise ValueError, "Zemantic expression must be a " \ "3 element tuple or provide IQuery" s, p, o = q q = Query(removeSecurityProxy(s), removeSecurityProxy(p), removeSecurityProxy(o)) elif not IQuery.providedBy(q): raise ValueError, "Zemantic expression must be a " \ "3 element tuple or provide IQuery" else: q = removeSecurityProxy(q) for result in c.query(q): yield result def __str__(self): return self._s def __repr__(self): return '' % self._s class RDFExpr(object): """\ Render results of a Zemantic expression into RDF XML. """ implements(ITALESExpression) def __init__(self, name, expr, engine): self._s = expr self._name = name self.engine = engine self.expr = self._compile(expr) def _compile(self, expression): m = _parse_expr(expression) if m: type = m.group(1) expr = expression[m.end():] else: type = "zemantic" expr = expression try: handler = self.engine.getTypes()[type] except KeyError: raise CompilerError, ('Unrecognized expression type "%s".' % type) return handler(type, expr, self.engine) def __call__(self, econtext): c = zapi.queryUtility(IZemantic) o = zapi.queryUtility(IZontology) if c is not None: econtext.setLocal('zem', c) if o is not None: econtext.setLocal('zon', o) econtext.setLocal('Any', None) econtext.setLocal('URIRef', URIRef) econtext.setLocal('BNode', BNode) econtext.setLocal('Literal', Literal) # eval each expression, stuffing the result in a Query object. # Query will raise an error if the argument is not proper # like. return ResultSet(self.expr(econtext)).rdfxml() def __str__(self): return self._s def __repr__(self): return '' % self._s def eval(expr, context=None): c = zapi.queryUtility(IZemantic, context=context) o = zapi.queryUtility(IZontology, context=context) econtext = Context(Engine, {}) if c is not None: econtext.setLocal('zem', c) if o is not None: econtext.setLocal('zon', o) econtext.setLocal('Any', None) econtext.setLocal('URIRef', URIRef) econtext.setLocal('BNode', BNode) econtext.setLocal('Literal', Literal) bytecode = Engine.compile(expr) return bytecode(econtext) from zope.app.pagetemplate.engine import Engine as PTEngine PTEngine.registerType('zemantic', ZemanticExpr) Engine.registerType('zemantic', ZemanticExpr)