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