Changes: Add PropertyInfoBase::predicateFunction method
[qtcontacts-tracker:qtcontacts-tracker.git] / src / dao / resourceinfo.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the Qt Mobility Components.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "resourceinfo.h"
43 #include "ontologies/nco.h"
44
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
46
47 CUBI_USE_NAMESPACE
48 CUBI_USE_NAMESPACE_RESOURCES
49
50 ////////////////////////////////////////////////////////////////////////////////////////////////////
51
52 const PropertyInfoBase piHasAffiliation = PropertyInfo<nco::hasAffiliation>();
53
54 ////////////////////////////////////////////////////////////////////////////////////////////////////
55
56 class ResourceInfoData : public QSharedData
57 {
58     friend class ClassInfoBase;
59     friend class InstanceInfoBase;
60     friend class PropertyInfoBase;
61     friend class ResourceInfo;
62
63 protected:
64     explicit ResourceInfoData(const QString &iri, const QVariant &value)
65         : m_value(value)
66         , m_iri(iri)
67     {
68     }
69
70 public:
71     virtual ~ResourceInfoData()
72     {
73     }
74
75 protected:
76     const QVariant m_value;
77     const QString &m_iri;
78 };
79
80 ////////////////////////////////////////////////////////////////////////////////////////////////////
81
82 class PropertyInfoData : public ResourceInfoData
83 {
84     friend class PropertyInfoBase;
85
86 protected:
87     typedef PropertyInfoBase::Subject Subject;
88
89     explicit PropertyInfoData(const ResourceValue &resource, const PredicateFunction &function,
90                               const QString &iri, const QString &name,
91                               Subject::Scheme domainScheme, Subject::Scheme rangeScheme,
92                               const QString &domainIri, const QString &rangeIri, bool singleValued)
93         : ResourceInfoData(iri, name)
94         , m_resource(resource)
95         , m_predicateFunction(function)
96         , m_domainScheme(domainScheme)
97         , m_rangeScheme(rangeScheme)
98         , m_domainIri(domainIri)
99         , m_rangeIri(rangeIri)
100         , m_singleValued(singleValued)
101         , m_conversion(0)
102         , m_caseSensitivity(Qt::CaseSensitive)
103         , m_parent(0)
104         , m_readOnly(false)
105         , m_optional(false)
106         , m_inverse(false)
107         , m_foreignKey(false)
108         , m_hasDetailUri(false)
109     {
110     }
111
112     const ResourceValue &   m_resource;
113     const PredicateFunction & m_predicateFunction;
114     const Subject::Scheme   m_domainScheme;
115     const Subject::Scheme   m_rangeScheme;
116     const QString &         m_domainIri;
117     const QString &         m_rangeIri;
118     bool                    m_singleValued;
119     const Conversion *      m_conversion;
120     Qt::CaseSensitivity     m_caseSensitivity;
121     PropertyInfoBase        m_parent;
122
123     bool m_readOnly     : 1;
124     bool m_optional     : 1;
125     bool m_inverse      : 1;
126     bool m_foreignKey   : 1;
127     bool m_hasDetailUri : 1;
128 };
129
130 ////////////////////////////////////////////////////////////////////////////////////////////////////
131
132 ResourceInfo::ResourceInfo(ResourceInfoData *data)
133     : d(data)
134 {
135 }
136
137 ResourceInfo::ResourceInfo(const ResourceInfo &other)
138     : d(other.d)
139 {
140 }
141
142 ResourceInfo::~ResourceInfo()
143 {
144 }
145
146 ResourceInfo &
147 ResourceInfo::operator=(const ResourceInfo &other)
148 {
149     return d = other.d, *this;
150 }
151
152 const QVariant &
153 ResourceInfo::value() const
154 {
155     return d->m_value;
156 }
157
158 const QString &
159 ResourceInfo::iri() const
160 {
161     if (not d) {
162         static const QString none;
163         return none;
164     }
165
166     return d->m_iri;
167 }
168
169 ////////////////////////////////////////////////////////////////////////////////////////////////////
170
171 ClassInfoBase::ClassInfoBase(const QString &iri, const QVariant &name)
172     : ResourceInfo(new ResourceInfoData(iri, name))
173 {
174 }
175
176 ////////////////////////////////////////////////////////////////////////////////////////////////////
177
178 InstanceInfoBase::InstanceInfoBase(const QString &iri, const QVariant &value)
179     : ResourceInfo(new ResourceInfoData(iri, value))
180 {
181 }
182
183 ////////////////////////////////////////////////////////////////////////////////////////////////////
184
185 PropertyInfoBase::PropertyInfoBase(const ResourceValue &resource, const PredicateFunction &function,
186                                    const QString &iri, const QString &name,
187                                    Subject::Scheme domainScheme, Subject::Scheme rangeScheme,
188                                    const QString &domainIri, const QString &rangeIri, bool singleValued)
189     : ResourceInfo(new PropertyInfoData(resource, function, iri, name, domainScheme, rangeScheme,
190                                         domainIri, rangeIri, singleValued))
191 {
192 }
193
194 PropertyInfoBase::PropertyInfoBase(PropertyInfoData *data)
195     : ResourceInfo(data)
196 {
197 }
198
199 PropertyInfoBase &
200 PropertyInfoBase::setReadOnly(bool value)
201 {
202     data()->m_readOnly = value;
203     return *this;
204 }
205 bool
206 PropertyInfoBase::isReadOnly() const
207 {
208     return data()->m_readOnly;
209 }
210
211 PropertyInfoBase &
212 PropertyInfoBase::setOptional(bool value)
213 {
214     data()->m_optional = value;
215     return *this;
216 }
217
218 bool
219 PropertyInfoBase::isOptional() const
220 {
221     return data()->m_optional;
222 }
223
224 PropertyInfoBase &
225 PropertyInfoBase::setInverse(bool value)
226 {
227     data()->m_inverse = value;
228     return *this;
229 }
230
231 bool
232 PropertyInfoBase::isInverse() const
233 {
234     return data()->m_inverse;
235 }
236
237 PropertyInfoBase &
238 PropertyInfoBase::setForeignKey(bool value)
239 {
240     data()->m_foreignKey = value;
241     return *this;
242 }
243
244 bool
245 PropertyInfoBase::isForeignKey() const
246 {
247     return data()->m_foreignKey;
248 }
249
250 PropertyInfoBase &
251 PropertyInfoBase::setHasDetailUri(bool value)
252 {
253     data()->m_hasDetailUri = value;
254     return *this;
255 }
256
257 bool
258 PropertyInfoBase::hasDetailUri() const
259 {
260     return data()->m_hasDetailUri;
261 }
262
263 PropertyInfoBase &
264 PropertyInfoBase::setCaseSensitivity(Qt::CaseSensitivity value)
265 {
266     data()->m_caseSensitivity = value;
267     return *this;
268 }
269
270 Qt::CaseSensitivity
271 PropertyInfoBase::caseSensitivity() const
272 {
273     return data()->m_caseSensitivity;
274 }
275
276 PropertyInfoBase &
277 PropertyInfoBase::setConversion(const Conversion *conversion)
278 {
279     data()->m_conversion = conversion;
280     return *this;
281 }
282
283 const Conversion *
284 PropertyInfoBase::conversion() const
285 {
286     return data()->m_conversion;
287 }
288
289 PropertyInfoBase &
290 PropertyInfoBase::setParent(const PropertyInfoBase &parent)
291 {
292     data()->m_parent = parent;
293     return *this;
294 }
295
296 const PropertyInfoBase &
297 PropertyInfoBase::parent() const
298 {
299     return data()->m_parent;
300 }
301
302 const ResourceValue &
303 PropertyInfoBase::resource() const
304 {
305     return data()->m_resource;
306 }
307
308 const PredicateFunction &
309 PropertyInfoBase::predicateFunction() const
310 {
311     return data()->m_predicateFunction;
312 }
313
314 PropertyInfoBase::Subject::Scheme
315 PropertyInfoBase::resourceIriScheme() const
316 {
317     Subject::Scheme scheme = (not isInverse() ? rangeScheme() : domainScheme());
318
319     if (Subject::None == scheme) {
320         const PropertyInfoBase &parentInfo = parent();
321
322         if (parentInfo) {
323             scheme = (not parentInfo.isInverse() ? domainScheme() : rangeScheme());
324         }
325     }
326
327     return scheme;
328 }
329
330 const QString &
331 PropertyInfoBase::resourceTypeIri() const
332 {
333     return not isInverse() ? rangeIri() : domainIri();
334 }
335
336 PropertyInfoBase::Subject::Scheme
337 PropertyInfoBase::domainScheme() const
338 {
339     return data()->m_domainScheme;
340 }
341
342 PropertyInfoBase::Subject::Scheme
343 PropertyInfoBase::rangeScheme() const
344 {
345     return data()->m_rangeScheme;
346 }
347
348 const QString &
349 PropertyInfoBase::domainIri() const
350 {
351     return data()->m_domainIri;
352 }
353
354 const QString &
355 PropertyInfoBase::rangeIri() const
356 {
357     return data()->m_rangeIri;
358 }
359
360 bool
361 PropertyInfoBase::singleValued() const
362 {
363     return data()->m_singleValued;
364 }
365
366 ////////////////////////////////////////////////////////////////////////////////////////////////////
367
368 PropertyInfoList::PropertyInfoList(const PropertyInfoList::ConstIterator &first,
369                                    const PropertyInfoList::ConstIterator &last,
370                                    const PropertyInfoList &context)
371     : QList<PropertyInfoBase>(context)
372 {
373     for(PropertyInfoList::ConstIterator pi = first; pi != last; ++pi) {
374         append(*pi);
375     }
376 }
377
378 bool
379 PropertyInfoList::startsWith(const PropertyInfoBase &predicate) const
380 {
381     return BaseType::startsWith(predicate);
382 }
383
384 bool
385 PropertyInfoList::startsWith(const QList<PropertyInfoBase> &otherChain) const
386 {
387     if (otherChain.length() > length()) {
388         return false;
389     }
390
391     for(int i = otherChain.length() - 1; i >= 0; --i) {
392         if (at(i) != otherChain.at(i)) {
393             return false;
394         }
395     }
396
397     return true;
398 }
399
400 bool
401 PropertyInfoList::hasInverseProperty() const
402 {
403     foreach(const PropertyInfoBase &pi, *this) {
404         if (pi.isInverse()) {
405             return true;
406         }
407     }
408
409     return false;
410 }
411
412 bool
413 PropertyInfoList::isSingleValued(bool strict) const
414 {
415     // We only search until size()-1 since we allow the last property to be
416     // mutivalued, we'll get the values coma-separated
417     for (int i = 0; i < size() - (strict ? 0 : 1); i++) {
418         if (not at(i).singleValued()) {
419             return false;
420         }
421     }
422
423     return true;
424 }
425
426 Pattern
427 PropertyInfoBase::bindProperty(const Value &subject, const Value &object) const
428 {
429     const ResourceValue predicate = ResourceValue(iri());
430
431     if (isInverse()) {
432         return Pattern(object, predicate, subject);
433     }
434
435     return Pattern(subject, predicate, object);
436 }