# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr## This file is part of CubicWeb.## CubicWeb is free software: you can redistribute it and/or modify it under the# terms of the GNU Lesser General Public License as published by the Free# Software Foundation, either version 2.1 of the License, or (at your option)# any later version.## CubicWeb is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more# details.## You should have received a copy of the GNU Lesser General Public License along# with CubicWeb. If not, see <http://www.gnu.org/licenses/>."""SPARQL integration"""__docformat__="restructuredtext en"fromyamsimportxyfromrqlimportTypeResolverExceptionfromlxmlimportetreefromlxml.builderimportEfromcubicweb.viewimportStartupView,AnyRsetViewfromcubicweb.webimportRedirect,form,formfields,formwidgetsasfwdgsfromcubicweb.web.viewsimportformstry:fromcubicweb.spa2rqlimportSparql2rqlTranslator,UnsupportedQueryexceptImportError:# fyzz not available (only a recommends)Sparql2rqlTranslator=NoneclassSparqlForm(forms.FieldsForm):__regid__='sparql'sparql=formfields.StringField(help=_('type here a sparql query'))resultvid=formfields.StringField(choices=((_('table'),'table'),(_('sparql xml'),'sparqlxml')),widget=fwdgs.Radio,value='table')form_buttons=[fwdgs.SubmitButton()]@propertydefaction(self):returnself._cw.url()classSparqlFormView(form.FormViewMixIn,StartupView):__regid__='sparql'defcall(self):form=self._cw.vreg['forms'].select('sparql',self._cw)self.w(form.render())sparql=self._cw.form.get('sparql')vid=self._cw.form.get('resultvid','table')ifsparql:try:qinfo=Sparql2rqlTranslator(self._cw.vreg.schema).translate(sparql)exceptTypeResolverException,exc:self.w(self._cw._('can not resolve entity types:')+u' '+unicode(exc))exceptUnsupportedQuery:self.w(self._cw._('we are not yet ready to handle this query'))exceptxy.UnsupportedVocabulary,exc:self.w(self._cw._('unknown vocabulary:')+u' '+unicode(exc))else:rql,args=qinfo.finalize()ifvid=='sparqlxml':url=self._cw.build_url('view',rql=(rql,args),vid=vid)raiseRedirect(url)rset=self._cw.execute(rql,args)self.wview(vid,rset,'null')## sparql resultset views #####################################################YAMS_XMLSCHEMA_MAPPING={'String':'string','Int':'integer','Float':'float','Boolean':'boolean','Datetime':'dateTime','Date':'date','Time':'time',# XXX the following types don't have direct mapping'Decimal':'string','Interval':'duration','Password':'string','Bytes':'base64Binary',}defxmlschema(yamstype):return'http://www.w3.org/2001/XMLSchema#%s'%YAMS_XMLSCHEMA_MAPPING[yamstype]classSparqlResultXmlView(AnyRsetView):"""The spec can be found here: http://www.w3.org/TR/rdf-sparql-XMLres/ """__regid__='sparqlxml'content_type='application/sparql-results+xml'templatable=Falsedefcall(self):# XXX handle UNIONrqlst=self.cw_rset.syntax_tree().children[0]varnames=[var.nameforvarinrqlst.selection]results=E.results()forrowidxinxrange(len(self.cw_rset)):result=E.result()forcolidx,varnameinenumerate(varnames):result.append(self.cell_binding(rowidx,colidx,varname))results.append(result)sparql=E.sparql(E.head(*(E.variable(name=name)fornameinvarnames)),results)self.w(u'<?xml version="1.0"?>\n')self.w(etree.tostring(sparql,encoding=unicode,pretty_print=True))defcell_binding(self,row,col,varname):celltype=self.cw_rset.description[row][col]ifself._cw.vreg.schema.eschema(celltype).final:cellcontent=self.view('cell',self.cw_rset,row=row,col=col)returnE.binding(E.literal(cellcontent,datatype=xmlschema(celltype)),name=varname)else:entity=self.cw_rset.get_entity(row,col)returnE.binding(E.uri(entity.absolute_url()),name=varname)defset_request_content_type(self):"""overriden to set the correct filetype and filename"""self._cw.set_content_type(self.content_type,filename='sparql.xml',encoding=self._cw.encoding)defregistration_callback(vreg):ifSparql2rqlTranslatorisnotNone:vreg.register_all(globals().values(),__name__)