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)})
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
) {
57 arg
<< QString::fromAscii( it
.key().toEncoded() ) << it
.value();
69 const QDBusArgument
& operator>>( const QDBusArgument
& arg
, Nepomuk::Search::Result
& result
)
72 // Signature: (sda{s(isss)})
80 result
= Nepomuk::Search::Result( QUrl::fromEncoded( uri
.toAscii() ), score
);
83 while ( !arg
.atEnd() ) {
89 result
.addRequestProperty( QUrl::fromEncoded( rs
.toAscii() ), node
);
99 QDBusArgument
& operator<<( QDBusArgument
& arg
, const Nepomuk::Search::Term
& term
)
102 // Signature: (ii(isss)sss)
104 // i -> comparator type
105 // (isss) -> Soprano::LiteralValue encoded as a Soprano::Node for simplicity
111 arg
.beginStructure();
112 arg
<< ( int )term
.type()
113 << ( int )term
.comparator()
114 << Soprano::Node( term
.value() )
115 << QString::fromAscii( term
.resource().toEncoded() )
117 << QString::fromAscii( term
.property().toEncoded() );
124 const QDBusArgument
& operator>>( const QDBusArgument
& arg
, Nepomuk::Search::Term
& term
)
127 // Signature: (ii(isss)sss)
129 // i -> comparator type
130 // (isss) -> Soprano::LiteralValue encoded as a Soprano::Node for simplicity
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
;
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() ) );
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
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})
189 // a(ii(isss)sss) -> array of terms (first is root term)
190 // a{iai} -> hash of term relations
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
);
207 arg
.beginMap( QVariant::Int
, qMetaTypeId
<QList
<int> >() );
208 for( QHash
<int, QList
<int> >::const_iterator it
= termRelations
.constBegin();
209 it
!= termRelations
.constEnd(); ++it
) {
211 arg
<< it
.key() << it
.value();
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
) {
221 arg
<< QString::fromAscii( rp
.first
.toEncoded() ) << rp
.second
;
233 Nepomuk::Search::Term
rebuildTermFromTermList( const QList
<Nepomuk::Search::Term
>& terms
,
234 const QHash
<int, QList
<int> >& termRelations
,
236 Nepomuk::Search::Term root
= terms
[index
];
237 foreach( int i
, termRelations
[index
] ) {
238 root
.addSubTerm( rebuildTermFromTermList( terms
, termRelations
, i
) );
244 const QDBusArgument
& operator>>( const QDBusArgument
& arg
, Nepomuk::Search::Query
& query
)
247 // Signature: (isa(ii(isss)sss)a{iai}ia{sb})
250 // a(ii(isss)sss) -> array of terms (first is root term)
251 // a{iai} -> hash of term relations
253 // a{sb} -> request properties
256 arg
.beginStructure();
258 int type
= Nepomuk::Search::Query::InvalidQuery
;
260 QList
<Nepomuk::Search::Term
> terms
;
261 QHash
<int, QList
<int> > termRelations
;
269 while ( !arg
.atEnd() ) {
273 arg
>> termIndex
>> indices
;
275 termRelations
.insert( termIndex
, indices
);
282 while ( !arg
.atEnd() ) {
284 bool optional
= true;
286 arg
>> prop
>> optional
;
288 query
.addRequestProperty( QUrl::fromEncoded( prop
.toAscii() ), optional
);
294 if ( Nepomuk::Search::Query::Type( type
) == Nepomuk::Search::Query::PlainQuery
) {
295 query
.setTerm( rebuildTermFromTermList( terms
, termRelations
) );
298 query
.setSparqlQuery( sparqlQuery
);
300 query
.setLimit( limit
);
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() );
314 arg
<< node
.toString();
316 arg
<< node
.language() << node
.dataType().toString();
322 const QDBusArgument
& operator>>( const QDBusArgument
& arg
, Soprano::Node
& node
)
327 arg
.beginStructure();
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
);
341 node
= Soprano::Node();