add more spacing
[personal-kdebase.git] / runtime / nepomuk / libnepomukquery / dbusoperators.cpp
blob0a80b8528e14cede0a91c4e40eb79ea27e2b2c5d
1 /*
2 Copyright (c) 2008 Sebastian Trueg <trueg@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #include "dbusoperators.h"
21 #include <QtDBus/QDBusMetaType>
24 Q_DECLARE_METATYPE(Nepomuk::Search::Result)
25 Q_DECLARE_METATYPE(Nepomuk::Search::Term)
26 Q_DECLARE_METATYPE(Nepomuk::Search::Query)
27 Q_DECLARE_METATYPE(Soprano::Node)
28 Q_DECLARE_METATYPE(QList<int>)
29 Q_DECLARE_METATYPE(QList<Nepomuk::Search::Result>)
32 void Nepomuk::Search::registerDBusTypes()
34 qDBusRegisterMetaType<Nepomuk::Search::Result>();
35 qDBusRegisterMetaType<QList<Nepomuk::Search::Result> >();
36 qDBusRegisterMetaType<Nepomuk::Search::Term>();
37 qDBusRegisterMetaType<Nepomuk::Search::Query>();
38 qDBusRegisterMetaType<Soprano::Node>();
42 QDBusArgument& operator<<( QDBusArgument& arg, const Nepomuk::Search::Result& result )
45 // Signature: (sda{s(isss)})
48 arg.beginStructure();
50 arg << QString::fromAscii( result.resourceUri().toEncoded() ) << result.score();
52 arg.beginMap( QVariant::String, qMetaTypeId<Soprano::Node>() );
54 QHash<QUrl, Soprano::Node> rp = result.requestProperties();
55 for ( QHash<QUrl, Soprano::Node>::const_iterator it = rp.constBegin(); it != rp.constEnd(); ++it ) {
56 arg.beginMapEntry();
57 arg << QString::fromAscii( it.key().toEncoded() ) << it.value();
58 arg.endMapEntry();
61 arg.endMap();
63 arg.endStructure();
65 return arg;
69 const QDBusArgument& operator>>( const QDBusArgument& arg, Nepomuk::Search::Result& result )
72 // Signature: (sda{s(isss)})
75 arg.beginStructure();
76 QString uri;
77 double score = 0.0;
79 arg >> uri >> score;
80 result = Nepomuk::Search::Result( QUrl::fromEncoded( uri.toAscii() ), score );
82 arg.beginMap();
83 while ( !arg.atEnd() ) {
84 QString rs;
85 Soprano::Node node;
86 arg.beginMapEntry();
87 arg >> rs >> node;
88 arg.endMapEntry();
89 result.addRequestProperty( QUrl::fromEncoded( rs.toAscii() ), node );
91 arg.endMap();
93 arg.endStructure();
95 return arg;
99 QDBusArgument& operator<<( QDBusArgument& arg, const Nepomuk::Search::Term& term )
102 // Signature: (ii(isss)sss)
103 // i -> type
104 // i -> comparator type
105 // (isss) -> Soprano::LiteralValue encoded as a Soprano::Node for simplicity
106 // s -> resource
107 // s -> field
108 // s -> property
111 arg.beginStructure();
112 arg << ( int )term.type()
113 << ( int )term.comparator()
114 << Soprano::Node( term.value() )
115 << QString::fromAscii( term.resource().toEncoded() )
116 << term.field()
117 << QString::fromAscii( term.property().toEncoded() );
118 arg.endStructure();
120 return arg;
124 const QDBusArgument& operator>>( const QDBusArgument& arg, Nepomuk::Search::Term& term )
127 // Signature: (ii(isss)sss)
128 // i -> type
129 // i -> comparator type
130 // (isss) -> Soprano::LiteralValue encoded as a Soprano::Node for simplicity
131 // s -> resource
132 // s -> field
133 // s -> property
136 arg.beginStructure();
137 int type = Nepomuk::Search::Term::InvalidTerm;
138 int comparator = Nepomuk::Search::Term::Equal;
139 Soprano::Node valueNode;
140 QString resource, field, property;
141 arg >> type
142 >> comparator
143 >> valueNode
144 >> resource
145 >> field
146 >> property;
147 term.setType( Nepomuk::Search::Term::Type( type ) );
148 term.setComparator( Nepomuk::Search::Term::Comparator( comparator ) );
149 if ( valueNode.isLiteral() )
150 term.setValue( valueNode.literal() );
151 if ( !resource.isEmpty() )
152 term.setResource( QUrl::fromEncoded( resource.toAscii() ) );
153 if ( !field.isEmpty() )
154 term.setField( field );
155 if ( !property.isEmpty() )
156 term.setProperty( QUrl::fromEncoded( property.toAscii() ) );
157 arg.endStructure();
159 return arg;
163 // streaming a Query object is a bit tricky as it is a set of nested Term objects
164 // DBus does not allow arbitrary nesting of objects, thus we use a little trick:
165 // We store all used Term objects in a list and use integer indices pointing into
166 // this list to describe the nesting within the Term objects. This also means that
167 // a Term's subTerm list is replaced with a list of indices
168 namespace {
170 * Build term relations for the last term in the list
172 void buildTermRelations( QList<Nepomuk::Search::Term>& terms, QHash<int, QList<int> >& termRelations ) {
173 QList<Nepomuk::Search::Term> subTerms = terms.last().subTerms();
174 int termIndex = terms.count()-1;
175 for ( int i = 0; i < subTerms.count(); ++i ) {
176 terms.append( subTerms[i] );
177 termRelations[termIndex].append( terms.count()-1 );
178 buildTermRelations( terms, termRelations );
183 QDBusArgument& operator<<( QDBusArgument& arg, const Nepomuk::Search::Query& query )
186 // Signature: (isa(ii(isss)sss)a{iai}ia{sb})
187 // i -> type
188 // s -> sparql query
189 // a(ii(isss)sss) -> array of terms (first is root term)
190 // a{iai} -> hash of term relations
191 // i -> limit
192 // a{sb} -> request properties
195 arg.beginStructure();
197 arg << ( int )query.type() << query.sparqlQuery();
199 QList<Nepomuk::Search::Term> terms;
200 QHash<int, QList<int> > termRelations;
201 if ( query.type() == Nepomuk::Search::Query::PlainQuery ) {
202 terms.append( query.term() );
203 buildTermRelations( terms, termRelations );
205 arg << terms;
207 arg.beginMap( QVariant::Int, qMetaTypeId<QList<int> >() );
208 for( QHash<int, QList<int> >::const_iterator it = termRelations.constBegin();
209 it != termRelations.constEnd(); ++it ) {
210 arg.beginMapEntry();
211 arg << it.key() << it.value();
212 arg.endMapEntry();
214 arg.endMap();
215 arg << query.limit();
217 arg.beginMap( QVariant::String, QVariant::Bool );
218 QList<Nepomuk::Search::Query::RequestProperty> requestProperties = query.requestProperties();
219 foreach( const Nepomuk::Search::Query::RequestProperty& rp, requestProperties ) {
220 arg.beginMapEntry();
221 arg << QString::fromAscii( rp.first.toEncoded() ) << rp.second;
222 arg.endMapEntry();
224 arg.endMap();
226 arg.endStructure();
228 return arg;
232 namespace {
233 Nepomuk::Search::Term rebuildTermFromTermList( const QList<Nepomuk::Search::Term>& terms,
234 const QHash<int, QList<int> >& termRelations,
235 int index = 0 ) {
236 Nepomuk::Search::Term root = terms[index];
237 foreach( int i, termRelations[index] ) {
238 root.addSubTerm( rebuildTermFromTermList( terms, termRelations, i ) );
240 return root;
244 const QDBusArgument& operator>>( const QDBusArgument& arg, Nepomuk::Search::Query& query )
247 // Signature: (isa(ii(isss)sss)a{iai}ia{sb})
248 // i -> type
249 // s -> sparql query
250 // a(ii(isss)sss) -> array of terms (first is root term)
251 // a{iai} -> hash of term relations
252 // i -> limit
253 // a{sb} -> request properties
256 arg.beginStructure();
258 int type = Nepomuk::Search::Query::InvalidQuery;
259 QString sparqlQuery;
260 QList<Nepomuk::Search::Term> terms;
261 QHash<int, QList<int> > termRelations;
262 int limit = 0;
264 arg >> type
265 >> sparqlQuery
266 >> terms;
268 arg.beginMap();
269 while ( !arg.atEnd() ) {
270 int termIndex = 0;
271 QList<int> indices;
272 arg.beginMapEntry();
273 arg >> termIndex >> indices;
274 arg.endMapEntry();
275 termRelations.insert( termIndex, indices );
277 arg.endMap();
279 arg >> limit;
281 arg.beginMap();
282 while ( !arg.atEnd() ) {
283 QString prop;
284 bool optional = true;
285 arg.beginMapEntry();
286 arg >> prop >> optional;
287 arg.endMapEntry();
288 query.addRequestProperty( QUrl::fromEncoded( prop.toAscii() ), optional );
290 arg.endMap();
292 arg.endStructure();
294 if ( Nepomuk::Search::Query::Type( type ) == Nepomuk::Search::Query::PlainQuery ) {
295 query.setTerm( rebuildTermFromTermList( terms, termRelations ) );
297 else {
298 query.setSparqlQuery( sparqlQuery );
300 query.setLimit( limit );
302 return arg;
306 QDBusArgument& operator<<( QDBusArgument& arg, const Soprano::Node& node )
308 arg.beginStructure();
309 arg << ( int )node.type();
310 if ( node.type() == Soprano::Node::ResourceNode ) {
311 arg << QString::fromAscii( node.uri().toEncoded() );
313 else {
314 arg << node.toString();
316 arg << node.language() << node.dataType().toString();
317 arg.endStructure();
318 return arg;
322 const QDBusArgument& operator>>( const QDBusArgument& arg, Soprano::Node& node )
325 // Signature: (isss)
327 arg.beginStructure();
328 int type;
329 QString value, language, dataTypeUri;
330 arg >> type >> value >> language >> dataTypeUri;
331 if ( type == Soprano::Node::LiteralNode ) {
332 node = Soprano::Node( Soprano::LiteralValue::fromString( value, dataTypeUri ), language );
334 else if ( type == Soprano::Node::ResourceNode ) {
335 node = Soprano::Node( QUrl::fromEncoded( value.toAscii() ) );
337 else if ( type == Soprano::Node::BlankNode ) {
338 node = Soprano::Node( value );
340 else {
341 node = Soprano::Node();
343 arg.endStructure();
344 return arg;