dce26ff4aedeb4c5523e1acbf02a5e34aeb7ec79
[smartapi.git] / Common / C++ / SmartAPI / smartapi / rdf / Variant.cpp
1 #include "Variant.h"
2 #include "smartapi/common/Tools.h"
3 #include "smartapi/common/ClassMapper.h"
4 #include "smartapi/common/PROPERTY.h"
5 #include "smartapi/common/RESOURCE.h"
6 #include "smartapi/model/Obj.h"
7 #include "smartapi/model/Activity.h"
8 #include "smartapi/model/Coordinates.h"
9 #include "smartapi/model/Input.h"
10 #include "smartapi/model/Output.h"
11 #include "smartapi/model/Evaluation.h"
12 #include "smartapi/model/Device.h"
13 #include "smartapi/model/Map.h"
14 #include "smartapi/model/WeatherServiceProvider.h"
15 #include "smartapi/model/ServiceProvider.h"
16 #include "smartapi/model/PhysicalEntity.h"
17 #include "smartapi/model/AbstractEntity.h"
18 #include "smartapi/model/Entity.h"
19 #include "smartapi/model/TimeSeries.h"
20 #include "smartapi/model/ValueObject.h"
21 #include "smartapi/model/Service.h"
22
23 #include <QtDebug>
24
25 Variant::Variant(QVariant v) : GraphItem()
26 {
27         value = v;
28         if (v.type() == QMetaType::QString)                     type = SMARTAPIVARIANT::STRING;
29         else if (v.type() == QMetaType::Double)                 type = SMARTAPIVARIANT::DOUBLE;
30         else if (v.type() == QMetaType::Float)                  type = SMARTAPIVARIANT::FLOAT;
31         else if (v.type() == QMetaType::Int)                    type = SMARTAPIVARIANT::INTEGER;
32         else if (v.type() == QMetaType::Bool)                   type = SMARTAPIVARIANT::BOOLEAN;
33         else if (v.type() == QMetaType::QUrl)                   type = SMARTAPIVARIANT::URI;
34         else if (v.type() == QMetaType::QDateTime)              type = SMARTAPIVARIANT::DATETIME;
35         else if (v.type() == QMetaType::QTime)                  type = SMARTAPIVARIANT::TIME;
36         else if (v.type() == QMetaType::QVariantList)   type = SMARTAPIVARIANT::LIST;
37         else if (v.type() == QMetaType::VoidStar)       {
38                 // If the source value is a Variant itself, remove the nesting. Variants should not carry
39                 // variants but other primitive objects
40                 type = SMARTAPIVARIANT::OBJ;
41                 if (Variant* vv = dynamic_cast<Variant*>((Variant*)v.value<void*>())) {
42                         type = (SMARTAPIVARIANT::VariantType)vv->getType();
43                         if (vv->getType() == SMARTAPIVARIANT::OBJ) {
44                                 Obj* copy = Tools::copy((Obj*)vv->getValue().value<void *>());
45                                 if (copy != NULL) {
46                                         value = qVariantFromValue((void*)copy);
47                                 } else {
48                                         type = SMARTAPIVARIANT::UNDEFINED;
49                                 }
50                         }
51                         else if (vv->getType() == SMARTAPIVARIANT::LIST) {
52                                 QVariantList dest;
53                                 QVariantList source = vv->getValue().toList();
54                                 for (int i = 0; i < source.length(); i++) {
55                                         dest.append(qVariantFromValue((void*)new Variant((Variant*)source.at(i).value<void *>())));
56                                 }
57                                 type = SMARTAPIVARIANT::LIST;
58                                 value = dest;
59                         }
60                         else {
61                                 value = vv->getValue();
62                         }
63                 }
64         }
65         else {
66                 type = SMARTAPIVARIANT::UNDEFINED;
67         }
68 }
69
70 Variant::Variant(GraphItem* i) : GraphItem()
71 {
72         if (Map* m = dynamic_cast<Map*>(i)) {
73                 type = SMARTAPIVARIANT::MAP;
74                 value = qVariantFromValue((void*)i);
75         } else {
76                 type = SMARTAPIVARIANT::OBJ;
77                 value = qVariantFromValue((void*)i);
78         }
79 }
80
81 Variant::Variant(Variant* v) : GraphItem()
82 {
83         if (v != NULL) {
84                 type = (SMARTAPIVARIANT::VariantType)v->getType();
85                 if (v->getType() == SMARTAPIVARIANT::OBJ) {
86                         Obj* copy = Tools::copy((Obj*)v->getValue().value<void *>());
87                         if (copy != NULL) {
88                                 value = qVariantFromValue((void*)copy);
89                         } else {
90                                 type = SMARTAPIVARIANT::UNDEFINED;
91                         }
92                 }
93                 else if (v->getType() == SMARTAPIVARIANT::LIST) {
94                         QVariantList dest;
95                         QVariantList source = v->getValue().toList();
96                         for (int i = 0; i < source.length(); i++) {
97                                 dest.append(qVariantFromValue((void*)new Variant((Variant*)source.at(i).value<void *>())));
98                         }
99                         value = dest;
100                 }
101                 else {
102                         value = v->getValue();
103                 }
104         }
105 }
106
107 Variant::~Variant()
108 {
109 }
110
111 void Variant::clearReferences(QSet<GraphItem*>* trash)
112 {
113         if (type == SMARTAPIVARIANT::OBJ) {
114                 ((Obj*)value.value<void *>())->destroyCascade(trash);
115         } else if (type == SMARTAPIVARIANT::MAP) {
116                 ((Map*)value.value<void *>())->destroyCascade(trash);
117         } else if (type == SMARTAPIVARIANT::LIST) {
118                 QVariantList l = value.toList();
119                 while (l.length() > 0) {
120                         ((Variant*)l.takeFirst().value<void *>())->destroyCascade(trash);
121                 }
122         }
123 }
124
125 RDFNode* Variant::serialize(Model* model)
126 {
127         switch (type) {
128         case SMARTAPIVARIANT::STRING: {
129                 return model->createLiteral(value.toString()); }
130         case SMARTAPIVARIANT::DOUBLE:
131                 return model->createTypedLiteral(value.toDouble(), Tools::getXsdString() + "double");
132         case SMARTAPIVARIANT::FLOAT:
133                 return model->createTypedLiteral(value.toFloat(), Tools::getXsdString() + "float");
134         case SMARTAPIVARIANT::INTEGER:
135                 return model->createTypedLiteral(value.toInt(), Tools::getXsdString() + "int");
136         case SMARTAPIVARIANT::BOOLEAN:
137                 return model->createTypedLiteral(value.toBool(), Tools::getXsdString() + "boolean");
138         case SMARTAPIVARIANT::URI:
139                 return model->createResource(value.toUrl());
140         case SMARTAPIVARIANT::DATETIME:
141                 return model->createTypedLiteral(Tools::dateToString(value.toDateTime()), Tools::getXsdString() + "dateTime");
142         case SMARTAPIVARIANT::TIME:
143                 return model->createTypedLiteral(Tools::timeToString(value.toTime()), Tools::getXsdString() + "time");
144         case SMARTAPIVARIANT::DURATION:
145                 return model->createTypedLiteral(value.toString(), Tools::getXsdString() + "duration");
146         case SMARTAPIVARIANT::LIST:
147                 {
148                         QVariantList mList = value.toList();
149                         List* rdfList = model->createList();
150                         for (int i = 0; i < mList.length(); i++) {
151                                 Variant* listItem = (Variant*)mList.at(i).value<void*>();
152                                 rdfList = rdfList->with(listItem->serialize(model));
153                         }
154                         return rdfList;
155                 }
156         case SMARTAPIVARIANT::MAP:
157                 return ((Map*)value.value<void *>())->serialize(model);
158         case SMARTAPIVARIANT::OBJ:
159                 return ((Obj*)value.value<void *>())->serialize(model);
160         default:
161                 return NULL;
162         }
163 }
164
165 Variant* Variant::parse(Statement* statement)
166 {
167         // get predicate
168         QString predicate = statement->getPredicateUriString();
169         // get object
170         raptor_term* objectNode = statement->getObject();
171
172         // if literal object
173         if (objectNode->type == RAPTOR_TERM_TYPE_LITERAL) {
174                 return new Variant(Tools::raptorLiteralToQVariant(objectNode->value.literal));
175         }
176
177         // if resource
178         if (statement->getResource() != NULL) {
179                 Resource* resource = statement->getResource();
180                 Obj* instanceClass = Tools::getResourceClass(resource);
181                 if (instanceClass) {
182                         QList<Statement*> sl = resource->findProperties();
183                         while (sl.length() > 0) {
184                                 instanceClass->parse(sl.at(0));
185                                 delete sl.takeFirst();
186                         }
187                         return new Variant(instanceClass);
188                 } else if (resource->canParseToList()) {
189                         return new Variant(resource->toList());
190                 } else {
191                         // type does not match with any built-in type, try using Object
192                         return new Variant(Obj::parse<Obj>(resource));
193                 }
194         }
195
196         // could not identify datatype
197         return new Variant("");
198 }
199
200 bool Variant::isUrl()
201 {
202         return type == SMARTAPIVARIANT::URI;
203 }
204
205 void Variant::set(QUrl url)
206 {
207         value = url;
208         type = SMARTAPIVARIANT::URI;
209 }
210
211 bool Variant::isString()
212 {
213         return type == SMARTAPIVARIANT::STRING;
214 }
215
216 void Variant::set(QString str)
217 {
218         value = str;
219         type = SMARTAPIVARIANT::STRING;
220 }
221
222 bool Variant::isInteger()
223 {
224         return type == SMARTAPIVARIANT::INTEGER;
225 }
226
227 void Variant::set(int i)
228 {
229         value = i;
230         type = SMARTAPIVARIANT::INTEGER;
231 }
232
233 bool Variant::isDouble()
234 {
235         return type == SMARTAPIVARIANT::DOUBLE;
236 }
237
238 void Variant::set(double d)
239 {
240         value = d;
241         type = SMARTAPIVARIANT::DOUBLE;
242 }
243
244 bool Variant::isFloat()
245 {
246         return type == SMARTAPIVARIANT::FLOAT;
247 }
248
249 void Variant::set(float f)
250 {
251         value = f;
252         type = SMARTAPIVARIANT::FLOAT;
253 }
254
255 bool Variant::isBoolean()
256 {
257         return type == SMARTAPIVARIANT::BOOLEAN;
258 }
259
260 void Variant::set(bool b)
261 {
262         value = b;
263         type = SMARTAPIVARIANT::BOOLEAN;
264 }
265
266 bool Variant::isDateTime()
267 {
268         return type == SMARTAPIVARIANT::DATETIME;
269 }
270
271 void Variant::set(QDateTime date)
272 {
273         value = date;
274         type = SMARTAPIVARIANT::DATETIME;
275 }
276
277 bool Variant::isTime()
278 {
279         return type == SMARTAPIVARIANT::TIME;
280 }
281
282 void Variant::set(QTime time)
283 {
284         value = time;
285         type = SMARTAPIVARIANT::TIME;
286 }
287
288 bool Variant::isDuration()
289 {
290         return type == SMARTAPIVARIANT::DURATION;
291 }
292
293 void Variant::set(Duration *duration)
294 {
295         value = duration->toString();
296         type = SMARTAPIVARIANT::DURATION;
297         delete duration;
298 }
299
300 bool Variant::isObj()
301 {
302         return type == SMARTAPIVARIANT::OBJ;
303 }
304
305 void Variant::set(Obj* obj)
306 {
307         this->value = qVariantFromValue((void*)obj);
308         type = SMARTAPIVARIANT::OBJ;
309 }
310
311 bool Variant::isItem()
312 {
313         return type == SMARTAPIVARIANT::OBJ;
314 }
315
316 void Variant::set(GraphItem* i)
317 {
318         this->value = qVariantFromValue((void*)i);
319         type = SMARTAPIVARIANT::OBJ;
320 }
321
322 bool Variant::isList()
323 {
324         return type == SMARTAPIVARIANT::LIST;
325 }
326
327 bool Variant::isLiteral()
328 {
329         return (isString() || isInteger() || isDouble() || isFloat() || isBoolean() || isDateTime() || isTime() || isDuration());
330 }
331
332 QVariant Variant::getValue()
333 {
334         return value;
335 }
336
337 int Variant::getType()
338 {
339         return type;
340 }
341
342 QString Variant::getAsString()
343 {
344         if (this->type == SMARTAPIVARIANT::OBJ) {
345                 void* vv = this->value.value<void*>();
346                 if (vv != NULL) {
347                         return ((Obj*)vv)->getIdentifierUri();
348                 } else {
349                         qDebug() << "Error in string conversion, the object stored in a Variant is NULL";
350                         return "";
351                 }
352         } else {
353                 return this->value.toString();
354         }
355 }
356
357 bool Variant::hasSameValue(Variant* other)
358 {
359         // FIXME:
360         // compare pointed values (not pointers) when both variants are objects
361         return (this->type == other->getType() && this->value == other->getValue());
362 }
363
364 QString Variant::toString()
365 {
366         return getAsString();
367 }
368
369 QUrl Variant::asUrl()                           { return value.toUrl(); }
370 QString Variant::asString()                     { return getAsString(); }
371 Obj* Variant::asObj()                           { return (Obj*)this->value.value<void*>(); }
372 GraphItem* Variant::asItem()            { return (GraphItem*)this->value.value<void*>(); }
373 int Variant::asInt()                            { return value.toInt(); }
374 double Variant::asDouble()                      { return (double)value.toFloat(); }
375 float Variant::asFloat()                        { return value.toFloat(); }
376 bool Variant::asBoolean()                       { return value.toBool(); }
377 QDateTime Variant::asDateTime()         { return value.toDateTime(); }
378 QTime Variant::asTime()                         { return value.toTime(); }
379 QString Variant::asDurationString()     { return value.toString(); }
380 Duration* Variant::asDuration()         { return new Duration(value.toString()); }
381
382 QVariantList Variant::makeVariantList(PropertyList<GraphItem*> l)
383 {
384         QVariantList ql;
385         for (PropertyListItem<GraphItem*>* i = l.firstItem(); i != NULL; i = i->next()) {
386                 Variant* a = new Variant(i->getItem());
387                 ql.append(qVariantFromValue((void *)(a)));
388         }
389         return ql;
390 }
391
392 QVariantList Variant::makeVariantList(QList<Obj*> l)
393 {
394         QVariantList ql;
395         for (int i = 0; i < l.length(); i++)
396                 ql.append(qVariantFromValue((void *)(new Variant(l.at(i)))));
397         return ql;
398 }
399
400 QVariantList Variant::makeVariantList(PropertyList<Obj*> l)
401 {
402         QVariantList ql;
403         for (PropertyListItem<Obj*>* i = l.firstItem(); i != NULL; i = i->next())
404                 ql.append(qVariantFromValue((void *)(new Variant(i->getItem()))));
405         return ql;
406 }
407
408 QVariantList Variant::makeVariantList(QList<Map*> l)
409 {
410         QVariantList ql;
411         for (int i = 0; i < l.length(); i++)
412                 ql.append(qVariantFromValue((void *)(new Variant(l.at(i)))));
413         return ql;
414 }
415
416 QList<Variant*> Variant::asList()
417 {
418         QList<Variant*> l;
419         QVariantList ql = value.toList();
420         for (int i = 0; i < ql.length(); i++)
421                 l.append((Variant *)(ql.at(i).value<void*>()));
422         return l;
423         
424 }
425         
426 // /Map* m = (Map*)(((Variant*)results.at(i)->asObj())->getValue().value<void*>());
427 Obj* Variant::nestedObj()
428 {
429         Variant* var = this;
430         Variant* v = NULL;
431         Variant* vv = NULL;
432         QVariant qv = var->getValue();
433         Obj* o = NULL;
434         int c = 0;
435         vv = (Variant*)qv.value<void*>();
436         while ((v = dynamic_cast<Variant*>(vv))) {
437                 var = v;
438                 v = NULL;
439                 qv = var->getValue();
440                 if (!qv.canConvert<void*>())
441                         break;
442                 else
443                         vv = (Variant*)qv.value<void*>();
444                 c++;
445         }
446         o = var->asObj();
447         return o;
448 }