c023582baeba82b0330e71251a9a9adcdf28cf43
[smartapi.git] / Common / C++ / SmartAPI / tests / TestSequences.cpp
1 #include <QCoreApplication>
2 #include <QString>
3 #include <QtDebug>
4 #include <QDateTime>
5 #include <QUrl>
6 #include <QFile>
7 #include <QNetworkAccessManager>
8 #include <QNetworkRequest>
9 #include <QNetworkReply>
10 #include <QUrlQuery>
11 #include <QEventLoop>
12 #include <QJsonDocument>
13 #include <QJsonObject>
14 #include <QElapsedTimer>
15 #include <openssl/rand.h>
16 #include <unistd.h>
17
18 #include "smartapi/common/CONTENTTYPES.h"
19 #include "smartapi/common/SERIALIZATION.h"
20 #include "smartapi/common/DATATYPE.h"
21 #include "smartapi/common/HttpMessage.h"
22 #include "smartapi/common/NS.h"
23 #include "smartapi/common/PROPERTY.h"
24 #include "smartapi/common/Tools.h"
25 #include "smartapi/common/SmartAPICrypto.h"
26 #include "smartapi/common/UnitConverter.h"
27 #include "smartapi/agents/OAuthAgent.h"
28 #include "smartapi/agents/RegistrationAgent.h"
29 #include "smartapi/agents/SearchAgent.h"
30 #include "smartapi/agents/SharingAgent.h"
31 #include "smartapi/agents/TransactionAgent.h"
32 #include "smartapi/factory/Factory.h"
33 #include "smartapi/factory/ActivityFactory.h"
34 #include "smartapi/factory/RequestFactory.h"
35 #include "smartapi/factory/ResponseFactory.h"
36 #include "smartapi/factory/NotificationFactory.h"
37 #include "smartapi/model/Request.h"
38 #include "smartapi/model/Response.h"
39 #include "smartapi/model/Notification.h"
40 #include "smartapi/model/Activity.h"
41 #include "smartapi/model/Direction.h"
42 #include "smartapi/model/Enumeration.h"
43 #include "smartapi/model/Error.h"
44 #include "smartapi/model/Input.h"
45 #include "smartapi/model/InterfaceAddress.h"
46 #include "smartapi/model/Device.h"
47 #include "smartapi/model/ValueObject.h"
48 #include "smartapi/model/PhysicalEntity.h"
49 #include "smartapi/model/Service.h"
50 #include "smartapi/model/Size.h"
51 #include "smartapi/model/SomeItems.h"
52 #include "smartapi/model/Map.h"
53 #include "smartapi/model/Offering.h"
54 #include "smartapi/model/Orientation.h"
55 #include "smartapi/model/Output.h"
56 #include "smartapi/model/PriceSpecification.h"
57 #include "smartapi/model/DistanceDependentPriceSpecification.h"
58 #include "smartapi/model/PropertyDependentPriceSpecification.h"
59 #include "smartapi/model/Restriction.h"
60 #include "smartapi/model/Ring.h"
61 #include "smartapi/model/SystemOfInterest.h"
62 #include "smartapi/model/TemporalContext.h"
63 #include "smartapi/model/UnitPriceSpecification.h"
64 #include "smartapi/model/Velocity.h"
65 #include "smartapi/model/Waypoints.h"
66 #include "smartapi/model/Waypoint.h"
67 #include "smartapi/model/Organization.h"
68 #include "smartapi/model/Address.h"
69 #include "smartapi/model/Capacity.h"
70 #include "smartapi/model/InterfaceAddress.h"
71
72 #include "smartapi/rdf/LinkedList.h"
73 #include "smartapi/rdf/OrderedList.h"
74 #include "smartapi/rdf/ItemizedList.h"
75 #include "smartapi/rdf/NudeList.h"
76 #include "smartapi/rdf/Model.h"
77
78 #include "RegisterDeregistertest.h"
79 #include "RegisterSearchTest.h"
80 #include <QThread>
81
82
83 bool modelReadTest()
84 {
85         QElapsedTimer timer;
86         timer.start();
87         QFile f("/home/jani/union-v1.0.ttl");
88
89         if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
90                 return false;
91         QByteArray all = f.readAll();
92         f.close();
93         qDebug() << "read file" << timer.elapsed();
94
95         Model* m = new Model();
96         m->read(all);
97         qDebug() << "parsed one" << timer.elapsed();
98         int parseOne = timer.elapsed();
99         delete m;
100
101         for (int i = 0; i < 10000; i++) {
102                 m = new Model();
103                 m->read(all);
104                 delete m;
105         }
106         int parseMulti = timer.elapsed();
107         qDebug() << "parsed multiple" << parseMulti << (parseMulti - parseOne);
108         return true;
109 }
110
111 bool variantTest()
112 {
113         Obj* o = new Obj();
114         Variant* v1 = new Variant(o);
115         Variant* v2 = new Variant(v1);
116         Variant* v3 = new Variant(v2);
117         Variant* v4 = new Variant(new Obj(v1->asObj()));
118         Variant* v5 = new Variant(v4);
119         
120         qDebug() << "Delete v1";
121         v1->destroyCascade();
122         qDebug() << "Delete v2";
123         v2->destroyCascade();
124         qDebug() << "Delete v3";
125         v3->destroyCascade();
126         qDebug() << "Delete v4";
127         v4->destroyCascade();
128         qDebug() << "Delete v5";
129         v5->destroyCascade();
130
131         return true;
132 }
133
134 bool serializeRequestTest()
135 {
136         int sampleValue = 9;
137
138         QString targetSystemUri = "http://localhost:8099/seas/v1.0/access/";
139         QString myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
140         QString targetId = "http://seasdemos.asema.com/csharp/controlcommandreceiver/Cabcd";
141         QString sourceIdentity = "http://seasexamples.asema.com/dataservers/timeseries";
142         QString myIdentity = "http://seasexamples.asema.com/datafetchers/timeseries";
143
144         qDebug() << "Test routine for request serialization";
145
146         QDateTime seriesEnd = QDateTime::currentDateTime();
147         QDateTime seriesStart = seriesEnd.addDays(-7);
148
149         QList<QPair<QString, QString>> request_vars;
150         request_vars.append(qMakePair(QString("Temperature"), QString("DegreeCelsius")));
151         request_vars.append(qMakePair(QString("Cloudiness"), QString("Percent")));
152         request_vars.append(qMakePair(QString("Precipitation"), QString("MilliMeter")));
153
154         Request* tsRequest = RequestFactory::create(myIdentity);
155         Activity* a = new Activity();
156         SystemOfInterest* system = new SystemOfInterest();
157         system->setSameAs(sourceIdentity);
158         tsRequest->addActivity(a);
159         tsRequest->setSystemOfInterest(system);
160
161         TemporalContext* tc = new TemporalContext();
162         tc->setStart(seriesStart);
163         tc->setEnd(seriesEnd);
164
165         Input* i = new Input();
166         i->setTemporalContext(tc);
167         a->setInput(i);
168
169         if (request_vars.length() == 1){
170                 tsRequest->setQuantity(NS__SMARTAPI + request_vars.at(0).first);
171                 tsRequest->setUnit(NS__SMARTAPI + request_vars.at(0).second);
172         } else {
173                 for (int idx = 0; idx < request_vars.length(); idx++) {
174                         ValueObject* v = new ValueObject();
175                         v->setQuantity(NS__SMARTAPI + request_vars.at(idx).first);
176                         v->setUnit(NS__SMARTAPI + request_vars.at(idx).second);
177                         v->setValue(new Variant(++sampleValue));
178                         tsRequest->add(NS__SMARTAPI + request_vars.at(idx).first, v);
179                 }
180         }
181
182         QString payload = Tools::toString(tsRequest, SERIALIZATION__JSON_LD);
183         printf("%s\n", payload.toUtf8().constData());
184         tsRequest->destroyCascade();
185
186         return true;
187 }
188
189 bool shortSerializeParseTest()
190 {
191         QString myId = "http://seasdemos.asema.com/cpluplus/controlcommandsender/Cabcd";
192
193         qDebug() << "Test routine for serialization + parse of a request (with activity)";
194
195         Activity* a = new Activity("http://asema.com/activitySeasIdentifier");
196         a->setMethod(RESOURCE__READ);
197         TemporalContext* tc = new TemporalContext();
198         tc->setStart(QDateTime::currentDateTime());
199         tc->setEnd(QDateTime::currentDateTime());
200
201         Response* resp = ResponseFactory::create(myId);
202         resp->setName("test request");
203         resp->setActivity(a);
204         resp->setTemporalContext(tc);
205         resp->setIdentifierUri("http://bogus.seas.identifier.uri");
206         a->setTemporalContext(new TemporalContext());
207
208         PhysicalEntity* entity = new PhysicalEntity("http://www.volvo.com/cars/electric");
209         entity->addType(RESOURCE__CAR);
210         entity->setName("A car");
211         entity->setCoordinates(60.185847, 24.867435);
212         a->addEntity(entity);
213
214         Error* e = new Error();
215         e->setErrorCode(100);
216         e->setErrorMessage("This is a dummy error for testing");
217         resp->addError(e);
218
219         QString payload = Tools::toString(resp, SERIALIZATION__TURTLE);
220         resp->destroyCascade();
221
222         qDebug() << "Serialized payload:";
223         printf("%s\n", payload.toLatin1().data());
224
225         qDebug() << "Parsing back the serialized payload...";
226
227         Response* tsRequest = (Response*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
228         Activity* a2 = tsRequest->firstActivity();
229         qDebug() << "hasTemporalContext? " << a2->hasTemporalContext();
230         qDebug() << "temporal context start" << a2->getTemporalContext()->getStart();
231         qDebug() << "is generated at " << tsRequest->getGeneratedAt();
232         qDebug() << "method" << a2->getMethod();
233         qDebug() << "entity" << a2->firstEntity()->getName();
234
235         qDebug() << "\nRe-serializing!";
236         QString reserializedPayload = Tools::toString(tsRequest, SERIALIZATION__JSON_LD);
237         printf("%s\n", reserializedPayload.toLatin1().data());
238         tsRequest->destroyCascade();
239
240         return true;
241 }
242
243 bool automaticSerializeParseTest()
244 {
245         QString myId = "http://seasdemos.asema.com/cpluplus/sometest/Cabcd";
246
247         qDebug() << "Test routine for serialization + parse of some object which must be deduced from the message automatically";
248
249         // Try first with an ID node at tope
250         Activity* a = new Activity("http://asema.com/activitySeasIdentifier");
251         Output* o = new Output();
252
253         TemporalContext* tc = new TemporalContext();
254         tc->setStart(QDateTime::currentDateTime());
255         tc->setEnd(QDateTime::currentDateTime());
256
257         a->setOutput(o);
258         o->setTemporalContext(tc);
259
260         QString payload = Tools::toString(a, SERIALIZATION__TURTLE);
261         a->destroyCascade();
262
263         qDebug() << "Serialized form:";
264         printf("%s\n", payload.toLatin1().data());
265
266         Obj* oo = Tools::fromStringAsObj(payload);
267         if (Activity* aa = dynamic_cast<Activity*>(oo)) {
268                 qDebug() << "Autoparsed, hasTemporalContext? " << aa->getOutputs().at(0)->hasTemporalContext();
269                 qDebug() << "temporal context start" << aa->getOutputs().at(0)->getTemporalContext()->getStart();
270         }
271         oo->destroyCascade();
272
273         qDebug() << "Serialize second round, now with fully blank top node.";
274         // Then a blank node at top
275         Activity* a2 = new Activity();
276         Output* o2 = new Output();
277
278         TemporalContext* tc2 = new TemporalContext();
279         tc2->setStart(QDateTime::currentDateTime());
280         tc2->setEnd(QDateTime::currentDateTime());
281
282         a2->setOutput(o2);
283         o2->setTemporalContext(tc2);
284
285         payload = Tools::toString(a2, SERIALIZATION__TURTLE);
286     a2->destroyCascade();
287
288         qDebug() << "Serialized form:";
289         printf("%s\n", payload.toLatin1().data());
290
291         qDebug() << "Parsing the string...";
292
293         Obj* oo2 = Tools::fromStringAsObj(payload);
294         if (Activity* aa2 = dynamic_cast<Activity*>(oo2)) {
295                 qDebug() << "Autoparsed, second round, hasTemporalContext? " << aa2->getOutputs().at(0)->hasTemporalContext();
296                 qDebug() << "temporal context start" << aa2->getOutputs().at(0)->getTemporalContext()->getStart();
297         }
298         oo2->destroyCascade();
299
300         return true;
301 }
302
303
304 bool longSerializeParseTest()
305 {
306         QString myId = "http://seasdemos.asema.com/cpluplus/controlcommandsender/Cabcd";
307         
308         qDebug() << "Test routine for serialization + parse of an activity";
309         
310         Activity* a = new Activity("http://asema.com/activitySeasIdentifier");
311         Input* i1 = new Input("http://input.uri", Input::TYPE_DATA);
312         i1->setName("data input");
313         Input* i2 = new Input("http://input2.uri", Input::TYPE_REFERENCE);
314         i2->setName("reference input");
315         a->setInput(i1);
316         a->addInput(i2);
317         Output* o1 = new Output("http://output.uri");
318         o1->setName("output 1");
319         Output* o2 = new Output("http://output.uri");
320         o2->setName("output 2");
321         a->setOutput(o1);
322         a->addOutput(o2);
323         
324         Availability* ab = new Availability();
325         ab->setIdentifierUri("http://availability.uri");
326         ab->setName("availability");
327         ab->setIsControlledBy("http://availability.controlled.by");
328         a->addAvailability(ab);
329         Availability* dab = new Availability();
330         dab->setIdentifierUri("http://data.availability.uri");
331         dab->setName("data availability");
332         a->addDataAvailability(dab);
333         
334         InterfaceAddress* iface1 = new InterfaceAddress();
335         iface1->setIdentifierUri("http://iface1.uri");
336         iface1->setName("eth0");
337         InterfaceAddress* iface2 = new InterfaceAddress();
338         iface2->setIdentifierUri("http://iface2.uri");
339         iface2->setType(RESOURCE__INTERFACEADDRESS);
340         iface2->addType(RESOURCE__BATTERY);
341         iface2->setName("eth1");
342         a->setInterface(iface1);
343         a->addInterface(iface2);
344         
345         Status* status = new Status();
346         status->setPercentage(50);
347         status->setCompleted(20);
348
349         Response* req = ResponseFactory::create(myId);
350         req->setSameAs("http://bogus.same.as");
351         req->setName("test request");
352         req->setActivity(a);
353         req->setMessageId(1);
354         req->setProcessId(2);
355         req->setStatus(status);
356         req->setIdentifierUri("http://bogus.seas.identifier.uri");
357         req->add("http://booleanProperty", true);
358         req->add("http://objectProperty", new Obj("http://foo.bar"));
359         req->add("http://stringProperty", "string value");
360         req->add("http://doubleProperty", -12.34);
361         req->add("http://integerProperty", 40);
362         req->add("http://datetimeProperty", QDateTime::currentDateTime());
363
364         QString payload = Tools::toString(req, SERIALIZATION__JSON_LD);
365         req->destroyCascade();
366         
367         qDebug() << "Serialized payload:";
368         qDebug() << payload;
369
370         qDebug() << "Parsing back the serialized payload...";
371
372         Model* model = Tools::fromString(payload, SERIALIZATION__JSON_LD);
373         Resource* res = Tools::getResourceByType(RESOURCE__RESPONSE, model);
374         Response* tsRequest = Obj::parse<Response>(res);
375         delete res;
376         delete model;
377         if (tsRequest->hasGeneratedBy())
378                 qDebug() << "is generated by " << tsRequest->getGeneratedBy();
379         qDebug() << "is generated at " << tsRequest->getGeneratedAt();
380         
381         qDebug() << "\nRe-serializing!";
382         QString reserializedPayload = Tools::toString(tsRequest, SERIALIZATION__JSON_LD);
383         qDebug() << reserializedPayload;
384         tsRequest->destroyCascade();
385
386         return true;
387 }
388
389 bool physicalEntityTest()
390 {
391         PhysicalEntity* entity = new PhysicalEntity();
392         
393         Size* size = new Size();
394         Velocity* speed = new Velocity();
395         Orientation* orientation = new Orientation();
396         Direction* direction = new Direction();
397         ValueObject* colorCoding = new ValueObject();
398         
399         size->setWidth(new ValueObject(NS__UNIT + "Centimeter", new Variant(100.2)));
400         size->setHeight(new ValueObject(NS__UNIT + "Centimeter", new Variant(301.9)));
401         size->setDepth(new ValueObject(NS__UNIT + "Centimeter", new Variant(11.222)));
402         
403         orientation->setYaw(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(270)));
404         orientation->setPitch(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(45)));
405         orientation->setRoll(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(301)));
406         
407         direction->setBearing(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(121)));
408         direction->setHeading(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(243)));
409
410         speed->setLinearVelocityX(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(3.4)));
411         speed->setLinearVelocityY(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(30.1)));
412         speed->setAngularVelocityY(new ValueObject(NS__UNIT + "RadianPerSecond", new Variant(54.3)));
413
414         colorCoding->setValue(new Variant("PANTONE"));
415         
416         entity->addType(RESOURCE__CAR);
417         entity->setName("This is a test entity");
418         entity->setVelocity(speed);
419         entity->setOrientation(orientation);
420         entity->setDirection(direction);
421         entity->setSize(size);
422         entity->add("colorCoding", colorCoding);
423         
424         entity->setCoordinates(60.185847, 24.867435);
425
426         Address* addr = new Address();
427         addr->setCity("Espoo");
428         addr->setCountry("Finland");
429         addr->setStreetAddress("Otakaari 1");
430         addr->setZipCode("02150");
431         entity->setAddress(addr);
432
433         entity->setWeight(new ValueObject(NS__UNIT + "Kilogram", new Variant(222)));
434         
435         QString serialized = Tools::toString(entity, SERIALIZATION__TURTLE);
436         qDebug() << "Serialized:";
437         printf("%s\n", serialized.toLatin1().data());
438         entity->destroyCascade();
439
440         qDebug() << "-------------------";      
441         PhysicalEntity* parsedEntity = (PhysicalEntity*)Tools::fromStringAsObj(serialized);
442         
443         qDebug() << "\nRe-serializing...";
444         QString reserializedPayload = Tools::toString(parsedEntity, SERIALIZATION__TURTLE);
445         printf("%s\n", reserializedPayload.toLatin1().data());
446
447         qDebug() << "---- Explain -----";
448         //parsedEntity->explain(true);
449         parsedEntity->destroyCascade(); // if explain is active, don't destroy (explain needs the object until ontologies have loaded)
450
451         return true;
452 }
453
454 bool waypointsTest()
455 {
456         Waypoints* waypoints = new Waypoints();
457
458         Waypoint* wp1 = new Waypoint();
459         Waypoint* wp2 = new Waypoint();
460         Waypoint* wp3 = new Waypoint();
461
462         waypoints->addWaypoint(wp1);
463         waypoints->addWaypoint(wp2);
464         waypoints->addWaypoint(wp3);
465
466         Address* loc1 = new Address();
467         Address* loc2 = new Address();
468         Address* loc3 = new Address();
469
470         Route* route = new Route;
471         route->addRoutePoint(new Coordinates(61.15, 25.89));
472         route->addRoutePoint(new Coordinates(61.14, 24.78));
473         route->addRoutePoint(new Coordinates(61.14, 24.61));
474
475         loc2->setCity("Espoo");
476         loc2->setCountry("Finland");
477         loc2->setStreetAddress("Otakaari 1");
478         loc2->setZipCode("02150");
479
480         wp1->setInstant(QDateTime::currentDateTime());
481         wp1->setAddress(loc1);
482         wp1->setCoordinates(new Coordinates(60.2, 24.1));
483
484         wp2->setAddress(loc2);
485         wp3->setAddress(loc3);
486         wp3->setRoute(route);
487
488
489         QString payload = Tools::toString(waypoints, SERIALIZATION__TURTLE);
490
491         qDebug() << "Serialized:";
492         printf("%s\n", payload.toLatin1().data());
493         waypoints->destroyCascade();
494
495         Obj* parsedObj = Tools::fromStringAsObj(payload);
496         QString reserialized = Tools::toString(parsedObj, SERIALIZATION__TURTLE);
497         qDebug() << "Re-Serialized:";
498         printf("%s\n", reserialized.toLatin1().data());
499
500         parsedObj->destroyCascade();
501         return true;
502 }
503
504 bool routeTest()
505 {
506         Route* route = new Route;
507         route->addRoutePoint(new Coordinates(61.00, 25.89));
508         route->addRoutePoint(new Coordinates(62.00, 26.78));
509         route->addRoutePoint(new Coordinates(63.00, 27.61));
510         Velocity* v = new Velocity();
511         v->setGroundSpeed(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(10200)));
512         route->setAverageVelocity(v);
513
514         QString payload = Tools::toString(route, SERIALIZATION__TURTLE);
515
516         qDebug() << "Serialized:";
517         printf("%s\n", payload.toLatin1().data());
518         route->destroyCascade();
519
520         Route* parsedObj = (Route*)Tools::fromStringAsObj(payload);
521         QString reserialized = Tools::toString(parsedObj, SERIALIZATION__TURTLE);
522         qDebug() << "Re-Serialized:";
523         printf("%s\n", reserialized.toLatin1().data());
524
525         qDebug() << "Ground speed on route" << parsedObj->getAverageVelocity()->getGroundSpeed()->getValue()->asDouble();
526         parsedObj->destroyCascade();
527         return true;
528 }
529
530 bool routeFetchTest()
531 {
532     //QNetworkAccessManager *networkManager = new QNetworkAccessManager();
533     //QEventLoop postWaitLoop;
534     //QString serviceUrl = "http://bemap-beta.benomad.com/bgis/seas/v1.0/access";
535         QString requesterIdentity = "http://seasexamples.asema.com/api/Crequest";
536
537         // Create a request
538         Request* r = RequestFactory::create(requesterIdentity);
539
540         // API payload data
541         Activity* a = new Activity();
542         Input* i = new Input();
543         a->addInput(i);
544         r->addActivity(a);
545
546         PhysicalEntity* trip = new PhysicalEntity();
547
548         trip->add("startCoordinates", new Coordinates(43.70059, 7.27696));
549         trip->add("stopCoordinates", new Coordinates(43.58035, 7.12125));
550         i->add("tripData", trip);
551         
552         PhysicalEntity* car = new PhysicalEntity();
553         car->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos"));
554         car->add("frontalAerodynamicCoefficient", new ValueObject(NS__UNIT + "SquareMeter", 0.75)); 
555         car->add("tireRollingResistanceCoefficient", new ValueObject(0.012));
556         car->add("gearEfficiencyCoefficient", new ValueObject(0.693));
557         car->add("batteryCapacity", new ValueObject(NS__UNIT + "KilowattHour", 22.0));
558         car->add("extraLoadWeight", new ValueObject(NS__UNIT + "Kilogram", 75.0));
559         car->add("auxiliaryEquipmentConsumption", new ValueObject(NS__UNIT + "Watt", 300.0));
560         car->add("maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 2.0));
561         car->add("maximumDeceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", -2.0));
562         car->add("maximumSpeed", new ValueObject(NS__UNIT + "KilometerPerHour", 90.0));
563         i->add("vehicleData", car);
564         
565         QString payload = Tools::toString(r, SERIALIZATION__TURTLE);
566         printf("%s\n", payload.toLatin1().data());
567         r->destroyCascade();
568         
569     /*
570         QNetworkRequest request(serviceUrl);
571         QByteArray authHash = QByteArray("Basic ") + QByteArray("smartapi:5Hq0j16818v1cDh507fP").toBase64();
572     request.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
573         request.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("seasClientTest"));
574         request.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("routing"));
575     request.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
576         request.setRawHeader(QByteArray("Authorization"), authHash);
577     request.setRawHeader(QByteArray("Content-Type"), QByteArray(CONTENT_TYPE__TURTLE));
578         
579         QNetworkReply* reply = networkManager->post(request, payload.toUtf8());
580         QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
581         postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
582         
583         QByteArray result = reply->readAll();
584         reply->deleteLater();
585         networkManager->deleteLater();
586         
587           qDebug() << "Result: " << result;
588      */
589         return true;
590 }
591
592 bool entityCopyTest()
593 {
594         Activity* a1 = new Activity();
595         PhysicalEntity* p1 = new PhysicalEntity("http://www.p1.com");
596         PhysicalEntity* p2 = new PhysicalEntity("http://www.p2.com");
597         ValueObject* vo = new ValueObject(22.0);
598
599         p1->addValueObject(vo);
600         a1->addEntity(p1);
601         a1->addEntity(p2);
602
603         PhysicalEntity* p3 = new PhysicalEntity(p1);
604         Tools::destroy(2, a1, p3);
605         qDebug() << "Destroyed all objects ok";
606         return true;
607 }
608
609 bool entityManagedByTest()
610 {
611         PhysicalEntity* p1 = new PhysicalEntity("http://www.p1.com");
612         ValueObject* vo = new ValueObject(22.0);
613         p1->addValueObject(vo);
614         p1->setManagedBy("http://www.p2.com");
615
616         QString serialized = Tools::toString(p1, SERIALIZATION__TURTLE);
617         p1->destroyCascade();
618
619         printf("%s\n", serialized.toUtf8().data());
620
621         Obj* parsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
622
623         parsedObj->turtlePrint();
624         parsedObj->destroyCascade();
625         qDebug() << "Destroyed all objects ok";
626         return true;
627 }
628
629 bool propertyListCopyTest()
630 {
631         Activity* a1 = new Activity();
632         PhysicalEntity* p1 = new PhysicalEntity("http://www.p1.com");
633         PhysicalEntity* p2 = new PhysicalEntity("http://www.p2.com");
634
635         a1->addEntity(p1);
636         a1->addEntity(p2);
637
638         // This list becomes a copy of Entities in a1. Once a1 is destroyed
639         // also the entities are destroyed. The list should now have a shorter length
640         PropertyList<Entity*> ents = a1->getEntities();
641         a1->destroyCascade();
642
643         // Ents is now a copy. The Entities in a1 are not destroyed because there are still references
644         // to them in ents. However, ents is in the call stack now and will be automatically destroyed.
645         return true;
646 }
647
648 bool propertyListingTest()
649 {
650         Entity* e = new Entity("http://www.test.com/test");
651         e->add("color", new ValueObject(new Variant("Dark blue")));
652         e->setName("Test entity");
653         e->setCoordinates(60.1, 18.2);
654         QList<QString> propNames = e->activePropertyNames();
655         qDebug() << propNames;
656         e->destroyCascade();
657         return propNames.length() == 2;
658 }
659
660 bool propertyTest()
661 {
662         Activity* a = new Activity();
663         Entity* e = new Entity("http://www.hella.com/lightClassification");
664
665         PhysicalEntity* car1 = new PhysicalEntity("http://www.mazda.com/car1");
666         PhysicalEntity* car2 = new PhysicalEntity("http://www.volvo.com/car2");
667
668         car1->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 2000));
669         car2->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
670
671         car1->add("frontalAerodynamicCoefficient", new ValueObject(NS__UNIT + "SquareMeter", 0.75));
672         car1->add("tireRollingResistanceCoefficient", new ValueObject(0.012));
673         car1->add("gearEfficiencyCoefficient", new ValueObject(0.693));
674         car1->add("batteryCapacity", new ValueObject(NS__UNIT + "KilowattHour", 22.0));
675         car1->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 2.0));
676
677         car2->add("color", new ValueObject(new Variant("Dark blue")));
678
679         a->addEntity(car1);
680         a->addEntity(car2);
681
682         e->add(NS__SMARTAPI + "Brightness", new ValueObject(NS__SMARTAPI + "brightness", NS__UNIT + "Lumen", 2112));
683         e->add("Color", new ValueObject(new Variant("BrightWhite")));
684         car1->add("frontLightEfficiency", e);
685
686         QString serialized = Tools::toString(a, SERIALIZATION__TURTLE);
687         a->destroyCascade();
688
689         printf("%s\n", serialized.toUtf8().data());
690
691         Obj* parsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
692
693         Activity* a1 = (Activity*)parsedObj;
694         PhysicalEntity* c1 = (PhysicalEntity*)a1->getEntities().first();
695         PhysicalEntity* c2 = (PhysicalEntity*)a1->getEntities().at(1);
696
697         qDebug() << "Car 1 -- id, weight quantity, weight value, front light brightness and front light color:"
698                         << c1->getIdentifierUri()
699                         << c1->getWeight()->getQuantity()
700                         << c1->getWeight()->getValueAsDouble()
701                         << c1->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getUnit()
702                         << c1->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getValueAsDouble()
703                         << c1->get<Entity>("frontLightEfficiency")->get<ValueObject>("Color")->getValueAsString();
704
705         qDebug() << "Car 2 -- id, weight and color:"
706                         << c2->getIdentifierUri()
707                         << c2->getWeight()->getValueAsDouble()
708                         << c2->get<ValueObject>("color")->getValueAsString();
709
710         QList<PrefixUriPair> addedPrefixes;
711         addedPrefixes << PrefixUriPair("custom", "http://custom.com");
712         QString reserialized = Tools::toString(parsedObj, SERIALIZATION__TURTLE, addedPrefixes);
713         parsedObj->destroyCascade();
714         printf("\n---\n%s\n", reserialized.toUtf8().data());
715
716         Obj* reParsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
717         Activity* a21 = (Activity*)reParsedObj;
718         PhysicalEntity* c21 = (PhysicalEntity*)a21->getEntities().first();
719         PhysicalEntity* c22 = (PhysicalEntity*)a21->getEntities().at(1);
720
721         qDebug() << "==== Re-read values ====";
722         qDebug() << "Car 1 -- id, weight quantity, weight value, front light brightness and front light color:"
723                         << c21->getIdentifierUri()
724                         << c21->getWeight()->getQuantity()
725                         << c22->getWeight()->getValueAsDouble()
726                         << c21->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getUnit()
727                         << c21->get<Entity>("frontLightEfficiency")->get<ValueObject>(NS__SMARTAPI + "Brightness")->getValueAsDouble()
728                         << c21->get<Entity>("frontLightEfficiency")->get<ValueObject>("Color")->getValueAsString();
729
730         qDebug() << "Car 2 -- id, weight and color:"
731                         << c22->getIdentifierUri()
732                         << c22->getWeight()->getValueAsDouble()
733                         << c22->get<ValueObject>("color")->getValueAsString();
734         reParsedObj->destroyCascade();
735         return true;
736 }
737
738 bool propertyRequestTest()
739 {
740         qDebug() << "\n\n=== The \"Give me everything\" request ===";
741         Request* rE = new Request("http://me.com/just/me/not/you");
742         Activity* aE = new Activity();
743         PhysicalEntity* car1E = new PhysicalEntity("http://www.mazda.com/supersmoothnewmodel");
744
745         rE->addActivity(aE);
746         aE->addEntity(car1E);
747
748         QString serialized = Tools::toString(rE, SERIALIZATION__TURTLE);
749         rE->destroyCascade();
750
751         printf("%s\n", serialized.toUtf8().data());
752
753         Request* parsedObj = Tools::parseRequest(serialized.toLatin1(), QByteArray(SERIALIZATION__TURTLE));
754         parsedObj->destroyCascade();
755
756
757         qDebug() << "\n\n=== The \"Give me something\" request ===";
758         Request* rS = new Request("http://me.com/definitely/just/me");
759         Activity* aS = new Activity();
760         PhysicalEntity* car1S = new PhysicalEntity("http://www.mazda.com/veryslickmodel");
761
762         rS->addActivity(aS);
763         aS->addEntity(car1S);
764
765         ValueObject* vo = new ValueObject();
766         vo->setUnit(NS__UNIT + "MeterPerSecondSquared");
767         car1S->addValueObject(vo);
768         car1S->addValueObject(new ValueObject(NS__QUANTITY + "InstantPower", NS__UNIT + "Watt"));
769
770         serialized = Tools::toString(rS, SERIALIZATION__TURTLE);
771         rS->destroyCascade();
772
773         printf("%s\n", serialized.toUtf8().data());
774
775         qDebug() << "\n\n=== The \"Give me this thing\" request ===";
776         Request* rT = new Request("http://me.com/solitaire/world/champ");
777         Activity* aT = new Activity();
778         PhysicalEntity* car1T = new PhysicalEntity("http://www.mazda.com/rustyoldmodel");
779
780         rT->addActivity(aT);
781         aT->addEntity(car1T);
782
783         ValueObject* accVo = new ValueObject();
784         accVo->setUnit(NS__UNIT + "MeterPerSecondSquared");
785         car1T->setWeight(new ValueObject(NS__QUANTITY + "Weight", NS__UNIT + "Kilogram"));
786         car1T->add(NS__SMARTAPI + "maximumAcceleration", accVo);
787         car1T->add("batteryCapacity", new ValueObject(NS__QUANTITY + "MaximumCharge", NS__UNIT + "KilowattHour"));
788         car1T->add(NS__SMARTAPI + "phase1Power", new ValueObject());
789         car1T->add(NS__SMARTAPI + "phase1Consumption", new ValueObject());
790         car1T->add(NS__SMARTAPI + "phase2Power", new ValueObject(NS__QUANTITY + "InstantPower", NS__UNIT + "Watt"));
791         car1T->add("http://alienproperties/et/call/home", new ValueObject("http://pointy.fingers/dial/a/number"));
792
793         serialized = Tools::toString(rT, SERIALIZATION__TURTLE);
794         rT->destroyCascade();
795
796         printf("%s\n", serialized.toUtf8().data());
797         parsedObj = (Request*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
798
799         PropertyList<Activity*> acts = parsedObj->getActivities();
800         Activity* pa = acts.at(0);
801         PhysicalEntity* pe = (PhysicalEntity*)pa->getEntities().first();
802         qDebug() << "Requesting" << pe->getIdentifierUri();
803         qDebug() << "Properties requested:" << pe->propertyNames();
804         qDebug() << "Request weight in" << pe->getWeight()->getUnit();
805         qDebug() << "Request battery capacity of " << pe->get<ValueObject>("batteryCapacity")->getQuantity() << "in" << pe->get<ValueObject>("batteryCapacity")->getUnit();
806         parsedObj->destroyCascade();
807         qDebug() << "Test done.";
808         return true;
809 }
810
811 bool timeseriesResponseTest()
812 {
813         Response* r = new Response("http://me.com/just/me/not/you");
814         Activity* a = new Activity();
815         TimeSeries* ts = new TimeSeries();
816
817         QList<GraphItem*> testList;
818         QDateTime now = QDateTime::currentDateTime();
819
820         for (int i = 0; i < 5; i++) {
821                 ValueObject* v = new ValueObject();
822                 v->setValue(new Variant(i));
823                 v->setInstant(now.addDays(i));
824                 testList.append(v);
825         }
826         ts->setList(testList);
827         a->setTimeSeries(ts);
828         r->addActivity(a);
829
830         QString serialized = Tools::toString(r, SERIALIZATION__TURTLE);
831         r->destroyCascade();
832
833         printf("%s\n", serialized.toUtf8().data());
834
835         Response* parsedObj = Tools::parseResponse(serialized.toLatin1(), QByteArray(SERIALIZATION__TURTLE));
836         parsedObj->destroyCascade();
837
838         qDebug() << "Test done.";
839         return true;
840 }
841
842 bool listSerializeParseTest()
843 {
844         QDateTime now = QDateTime::currentDateTime();
845         
846         TimeSeries* ts = new TimeSeries();
847         
848         QList<GraphItem*> testList;
849         
850         for (int i = 0; i < 5; i++) {
851                 Evaluation* e = new Evaluation();
852                 e->setValue(new Variant(i));
853                 e->setInstant(now.addDays(i));
854
855                 testList.append(e);
856         }
857         ts->setList(testList);
858         
859         QString stringData = Tools::toString(ts, SERIALIZATION__TURTLE);
860         ts->destroyCascade();
861         
862         qDebug() << "Serialized data:";
863         printf("%s\n", stringData.toUtf8().data());
864
865         qDebug() << "Parsing back the serialized data...";
866
867         TimeSeries* tsParsed = (TimeSeries*)Tools::fromStringAsObj(stringData, SERIALIZATION__TURTLE);
868
869         if (tsParsed->hasList()) {
870                 QList<GraphItem*> tsl = tsParsed->getList().toQList();
871                 qDebug() << "has list" << tsl.length();
872                 for (int j = 0; j < tsl.length(); j++) {
873                         Evaluation* e = (Evaluation*)tsl.at(j);
874                         QString instant = e->getInstant().toString();
875                         int value = e->getValue()->getValue().toInt();
876                         qDebug() << "Value:" << instant << value;
877                         if (value == j) {
878                                 qDebug() << "value ok";
879                         } else {
880                                 return false;
881                         }
882                         int msecDiff = now.addDays(j).msecsTo(QDateTime::fromString(instant, "ddd MMM dd HH:mm:ss yyyy"));
883                         if ((msecDiff < 1000) && (msecDiff > -1000)) {
884                                 qDebug() << "timestamp ok";
885                         } else {
886                                 return false;
887                         }
888                 }
889         } else {
890                 return false;
891         }
892         tsParsed->destroyCascade();
893
894         return true;
895 }
896
897 bool listSpeedTest()
898 {
899         Model* model = Factory::createModel();
900         QString stringData;
901         int i = 0;
902         LinkedList* ll = new LinkedList(model);
903         OrderedList* ol = new OrderedList(model);
904         ItemizedList* il = new ItemizedList(model);
905         NudeList* nl = new NudeList(model);
906         QVariantList ql;
907         
908         ll->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "linked"));
909         ol->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "ordered"));
910         il->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "itemized"));
911         nl->setBaseObject(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "nude"));
912
913         //for (i = 0; i < 3000000; i++) {
914         for (i = 0; i < 5; i++) {
915                 ll->append(new Variant(i), true);
916                 ol->append(new Variant(i), true);
917                 il->append(new Variant(i), true);
918                 nl->append(new Variant(i), true);
919                 ql << i;
920         }
921         
922         QVariantMap m;
923         m.insert("a", ql);
924         qDebug() << "JSON list";
925         QDateTime jStart = QDateTime::currentDateTime();
926         QJsonObject jObject = QJsonObject::fromVariantMap(m);
927         QJsonDocument jData;
928         jData.setObject(jObject);
929         QByteArray data =  jData.toJson();
930         QDateTime jEnd = QDateTime::currentDateTime();
931         
932         qDebug() << "Ordered list";
933         QDateTime oStart = QDateTime::currentDateTime();
934         stringData = Tools::toString(ol, SERIALIZATION__TURTLE);
935         QDateTime oEnd = QDateTime::currentDateTime();
936         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
937
938         qDebug() << "Itemized list";
939         QDateTime iStart = QDateTime::currentDateTime();
940         stringData = Tools::toString(il, SERIALIZATION__TURTLE);
941         QDateTime iEnd = QDateTime::currentDateTime();
942         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
943         
944         qDebug() << "Nude list";
945         QDateTime nStart = QDateTime::currentDateTime();
946         stringData = Tools::toString(nl, SERIALIZATION__TURTLE);
947         QDateTime nEnd = QDateTime::currentDateTime();
948         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
949
950         qDebug() << "Linked list";
951         QDateTime lStart = QDateTime::currentDateTime();
952         stringData = Tools::toString(ll, SERIALIZATION__TURTLE);
953         QDateTime lEnd = QDateTime::currentDateTime();
954         printf("\nOutput:\n%s\n", stringData.toUtf8().data());
955
956         qDebug() << "RESULTS";
957         qDebug() << "Ordered list" << oStart.msecsTo(oEnd)/1000.0;
958         qDebug() << "Unordered list" << iStart.msecsTo(iEnd)/1000.0;
959         qDebug() << "Nude list" << nStart.msecsTo(nEnd)/1000.0;
960         qDebug() << "Linked list" << lStart.msecsTo(lEnd)/1000.0;
961         qDebug() << "JSON reference" << jStart.msecsTo(jEnd)/1000.0;
962         
963         // Note that the lists do not need to be deleted, they are added directly to the resource
964         delete model;
965         return true;
966 }
967
968 bool baseObjectListSerializeParseTest()
969 {
970         Model* model = Factory::createModel();
971         ValueObject* base1 = new ValueObject();
972         ValueObject* base2 = new ValueObject();
973         ValueObject* base3 = new ValueObject();
974         ValueObject* base4 = new ValueObject();
975
976         base1->setUnit(NS__UNIT + "Centimeter");
977         base2->setUnit(NS__UNIT + "Meter");
978         base3->setUnit(NS__UNIT + "Millimeter");
979         base4->setUnit(NS__UNIT + "Kilometer");
980
981         // Explicitly create lists
982         LinkedList* ll = new LinkedList(model);
983         OrderedList* ol = new OrderedList(model);
984         ItemizedList* il = new ItemizedList(model);
985         NudeList* nl = new NudeList(model);
986         OrderedList* cl = new OrderedList(model);
987
988         ll->setBaseObject(base1);
989         il->setBaseObject(base2);
990         ol->setBaseObject(base3);
991         nl->setBaseObject(base4);
992
993         ll->setBaseObjectProperty(PROPERTY__FRESHNESS);
994         il->setBaseObjectProperty(PROPERTY__FRESHNESS);
995         ol->setBaseObjectProperty(PROPERTY__FRESHNESS);
996         nl->setBaseObjectProperty(PROPERTY__FRESHNESS);
997
998         for (int i = 0; i < 5; i++) {
999                 ll->append(new Variant(i), true);
1000                 ol->append(new Variant(i), true);
1001                 il->append(new Variant(i), true);
1002                 nl->append(new Variant(i), true);
1003         }
1004
1005         // add string
1006         ol->append(new Variant("Test item"), true);
1007         // or integer
1008         ol->append(new Variant(5), true);
1009         // or double
1010         ol->append(new Variant(3.4), true);
1011         // or boolean
1012         ol->append(new Variant(true), true);
1013         // or Date
1014         ol->append(new Variant(QDateTime::currentDateTime()), true);
1015         // or Time
1016         ol->append(new Variant(QTime::currentTime()), true);
1017
1018         Evaluation* item = new Evaluation();
1019         // add to list
1020         ol->append(new Variant(item), true);
1021
1022         qDebug() << "Linked list";
1023         QString stringData = Tools::toString(ll, SERIALIZATION__TURTLE);
1024         printf("%s\n", stringData.toUtf8().data());
1025
1026         qDebug() <<  "Itemized list";
1027         stringData = Tools::toString(il, SERIALIZATION__TURTLE);
1028         printf("%s\n", stringData.toUtf8().data());
1029
1030         qDebug() <<  "Ordered list";
1031         stringData = Tools::toString(ol, SERIALIZATION__TURTLE);
1032         printf("%s\n", stringData.toUtf8().data());
1033
1034         qDebug() <<  "Nude list";
1035         stringData = Tools::toString(nl, SERIALIZATION__TURTLE);
1036         printf("%s\n", stringData.toUtf8().data());
1037
1038         qDebug() << "Copied list";
1039         stringData = Tools::toString(cl, SERIALIZATION__TURTLE);
1040         printf("%s\n", stringData.toUtf8().data());
1041
1042         for ( int i = 0; i < cl->size(); i++ ) {
1043                 // get item at position
1044                 Variant* item = (Variant*)cl->get(i);
1045         }
1046
1047         delete model;
1048         return true;
1049 }
1050
1051 bool simpleTimeSeriesTest()
1052 {
1053         TimeSeries* timeSeries = new TimeSeries();
1054
1055         timeSeries->setQuantity(NS__QUANTITY + "Weight");
1056         timeSeries->setUnit(NS__UNIT + "Kilogram");
1057         timeSeries->setTimeStep("PT1S");
1058
1059         // add start datetime for timeseries
1060         timeSeries->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1061
1062         SystemOfInterest* systemOfInterest = new SystemOfInterest();
1063         systemOfInterest->setSameAs("http://seasexamples.asema.com/api/Ccommand");
1064         timeSeries->setSystemOfInterest(systemOfInterest);
1065
1066         for (int i = 0; i < 5; i++) {
1067                 timeSeries->addListItem(new Variant(i));
1068         }
1069         QString stringData = Tools::toString(timeSeries, SERIALIZATION__TURTLE);
1070         printf("%s\n", stringData.toUtf8().data());
1071         timeSeries->destroyCascade();
1072
1073         return true;
1074 }
1075
1076 bool valueObjectTimeSeriesTest()
1077 {
1078         TimeSeries* timeSeries = new TimeSeries();
1079         for (int i = 0; i < 5; i++) {
1080                 ValueObject* vo = new ValueObject();
1081                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
1082                 vo->setUnit(RESOURCE__KILOWATTHOUR);
1083                 vo->setInstant(QDateTime::currentDateTime().addSecs(60*i));
1084                 vo->setValue(i);
1085                 timeSeries->addListItem(vo);
1086         }
1087
1088         // add start datetime for timeseries
1089         timeSeries->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1090
1091         QString stringData = Tools::toString(timeSeries, SERIALIZATION__TURTLE);
1092         printf("%s\n", stringData.toUtf8().data());
1093         timeSeries->destroyCascade();
1094
1095         return true;
1096 }
1097
1098 bool substitutiveValueObjectTimeSeriesTest()
1099 {
1100         TimeSeries* timeSeries = new TimeSeries();
1101         timeSeries->setBaseList(new ItemizedList());
1102         for (int i = 0; i < 5; i++) {
1103                 ValueObject* vo = new ValueObject();
1104                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
1105                 vo->setUnit(RESOURCE__KILOWATTHOUR);
1106                 vo->setInstant(QDateTime::currentDateTime().addSecs(60*i));
1107                 vo->setValue(i);
1108                 timeSeries->addListItem(new Variant(vo));
1109         }
1110
1111         // add start datetime for timeseries
1112         timeSeries->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1113
1114         QString stringData = Tools::toString(timeSeries, SERIALIZATION__TURTLE);
1115         printf("%s\n", stringData.toUtf8().data());
1116         timeSeries->destroyCascade();
1117
1118         return true;
1119 }
1120
1121 bool timeSeriesManipulationTest()
1122 {
1123         TimeSeries* timeSeries = new TimeSeries();
1124         timeSeries->setBaseList(new ItemizedList());
1125
1126         for (int i = 0; i < 5; i++) {
1127                 ValueObject* vo = new ValueObject();
1128                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
1129                 vo->setUnit(RESOURCE__KILOWATTHOUR);
1130                 vo->setInstant(QDateTime::currentDateTime().addSecs(60*i));
1131                 vo->setValue(i);
1132                 timeSeries->addListItem(vo);
1133         }
1134
1135         for ( int i = 0; i < timeSeries->getListSize(); i++ ) {
1136                 // assuming that the base object is ValueObject
1137                 Variant* item = (Variant*)timeSeries->getListItem(i);
1138                 if (item != NULL) {
1139                         QDateTime timeStamp = ((ValueObject*)item)->getInstant();
1140                         QString quantity = ((ValueObject*)item)->getQuantity();
1141                         QString unit = ((ValueObject*)item)->getUnit();
1142                 }
1143         }
1144
1145         TimeSeries* timeSeriesI = new TimeSeries(new NudeList());
1146
1147         Evaluation* baseObject = new Evaluation();
1148         baseObject->setQuantity(RESOURCE__ENERGYANDWORK);
1149         baseObject->setUnit(RESOURCE__KILOWATTHOUR);
1150         timeSeriesI->setBaseObject(baseObject);
1151
1152         // add start datetime for timeseries
1153         timeSeriesI->setTemporalContext(new TemporalContext(QDateTime::currentDateTime()));
1154
1155         // add timestep (1 second interval between data items)
1156         timeSeriesI->setTimeStep("PT1S");
1157
1158         // add three items with different values
1159         for ( int i = 0; i < 5; i++ ) {
1160                 timeSeriesI->addListItem(new Variant(i));
1161         }
1162
1163         QString stringData = Tools::toString(timeSeriesI, SERIALIZATION__TURTLE);
1164         printf("%s\n", stringData.toUtf8().data());
1165         timeSeriesI->destroyCascade();
1166         timeSeries->destroyCascade();
1167         return true;
1168 }
1169
1170
1171 bool baseObjectTimeSeriesTest()
1172 {
1173         bool parsedOk = false;
1174         TimeSeries* ts = new TimeSeries();
1175         ValueObject* baseObject = new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos");
1176         ts->setBaseObject(baseObject);
1177
1178         for (int d = 0; d < 10; d++) {
1179                 ts->addListItem(new ValueObject(QDateTime::currentDateTime().addSecs(60*d), d));
1180         }
1181         QString serialized = Tools::toString(ts, SERIALIZATION__TURTLE);
1182         ts->destroyCascade();
1183         printf("%s\n", serialized.toUtf8().data());
1184         qDebug() << "------------------";
1185
1186         TimeSeries* tsParsed = (TimeSeries*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
1187         qDebug() << "The parsed base object" << tsParsed->getBaseObject();
1188         if (tsParsed->getBaseObject() != NULL) parsedOk = true;
1189         serialized = Tools::toString(tsParsed, SERIALIZATION__TURTLE);
1190         tsParsed->destroyCascade();
1191         printf("\nReserialized:\n%s\n", serialized.toUtf8().data());
1192
1193         return parsedOk;
1194 }
1195
1196 bool substitutiveTimeSeriesParseTest()
1197 {
1198         bool parsedOk = false;
1199         TimeSeries* ts = new TimeSeries();
1200         ts->setBaseList(new OrderedList());
1201         ValueObject* baseObject = new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos");
1202         ts->setBaseObject(baseObject);
1203         ts->setBaseObjectProperty(PROPERTY__WEIGHT);
1204
1205         for (int d = 0; d < 10; d++) {
1206                 ts->addListItem(new ValueObject(QDateTime::currentDateTime().addSecs(60*d), d));
1207         }
1208         QString serialized = Tools::toString(ts, SERIALIZATION__TURTLE);
1209         ts->destroyCascade();
1210         printf("%s\n", serialized.toUtf8().data());
1211         qDebug() << "------------------";
1212
1213         TimeSeries* tsParsed = (TimeSeries*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
1214         if (tsParsed->getBaseObject() != NULL) parsedOk = true;
1215         serialized = Tools::toString(tsParsed, SERIALIZATION__TURTLE);
1216         tsParsed->destroyCascade();
1217         printf("\nReserialized:\n%s\n", serialized.toUtf8().data());
1218
1219         return parsedOk;
1220 }
1221
1222 bool networkTimeSeriesTest()
1223 {
1224         QUrl serviceUrl = QUrl("http://127.0.0.1:8099/seas/v1.0/access/");
1225         QString myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1226
1227         QNetworkAccessManager *networkManager = new QNetworkAccessManager();
1228         QEventLoop postWaitLoop;
1229         
1230         Request* tsRequest = RequestFactory::create(myId);
1231
1232         Activity* a = new Activity();
1233         QDateTime seriesEnd = QDateTime::currentDateTime();
1234         QDateTime seriesStart = seriesEnd.addDays(-1);
1235
1236         // system of interest
1237         SystemOfInterest* systemOfInterest = new SystemOfInterest();
1238         systemOfInterest->setSameAs("http://seasexamples.asema.com/api/Ctimeseries");
1239         tsRequest->setSystemOfInterest(systemOfInterest);
1240
1241         TemporalContext* tc = new TemporalContext();
1242         tc->setStart(seriesStart);
1243         tc->setEnd(seriesEnd);
1244
1245         tsRequest->addActivity(a);
1246         Input* i = new Input();
1247         i->setTemporalContext(tc);
1248         a->setInput(i);
1249
1250         ValueObject* v1 = new ValueObject();
1251         v1->setQuantity(NS__SMARTAPI + "Temperature");
1252         v1->setUnit(NS__SMARTAPI + "DegreeCelsius");
1253         tsRequest->add(NS__SMARTAPI + "Temperature", v1);
1254
1255         ValueObject* v2 = new ValueObject();
1256         v2->setQuantity(NS__SMARTAPI + "Cloudiness");
1257         v2->setUnit(NS__SMARTAPI + "Percent");
1258         tsRequest->add(NS__SMARTAPI + "Cloudiness", v2);
1259
1260         ValueObject* v3 = new ValueObject();
1261         v3->setQuantity(NS__SMARTAPI + "Precipitation");
1262         v3->setUnit(NS__SMARTAPI + "Millimeter");
1263         tsRequest->add(NS__SMARTAPI + "Precipitation", v3);
1264
1265         QString payload = Tools::toString(tsRequest, SERIALIZATION__TURTLE);
1266         tsRequest->destroyCascade();
1267         
1268         QNetworkRequest request(serviceUrl);
1269         request.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
1270         request.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("1"));
1271         request.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("fetchData"));
1272         request.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
1273         
1274         QNetworkReply* reply = networkManager->post(request, payload.toUtf8());
1275         QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
1276         postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
1277         
1278         QByteArray result = reply->readAll();
1279         reply->deleteLater();
1280         networkManager->deleteLater();
1281
1282         qDebug() << "Result: " << result;
1283         
1284         Model* m = Tools::fromString(QString(result), SERIALIZATION__TURTLE);
1285         Resource* res = Tools::getResourceByType(RESOURCE__RESPONSE, m);
1286         Evaluation* tsResponse = Obj::parse<Evaluation>(res);
1287         delete res;
1288         delete m;
1289
1290         if (tsResponse->hasTemporalContext()) {
1291                 qDebug() << "Received timeseries";
1292                 if (tsResponse->getTemporalContext()->hasStart() && tsResponse->getTemporalContext()->hasEnd()) {
1293                         qDebug() << "starts " << tsResponse->getTemporalContext()->getStart();
1294                         qDebug() << "ends " << tsResponse->getTemporalContext()->getEnd();
1295                 }
1296         }
1297         
1298         if (tsResponse->hasTimeSerie()) {
1299                 QList<TimeSeries*> l = tsResponse->getTimeSeries().toQList();
1300                 for (int i = 0; i < l.length(); i++) {
1301                         TimeSeries* ts = l.at(i);
1302                         if (ts->hasList()) {
1303                                 QList<GraphItem*> tsl = ts->getList().toQList();
1304                                 for (int j = 0; j < tsl.length(); j++) {
1305                                         Evaluation* e = (Evaluation*)tsl.at(j);
1306                                         qDebug() << "Value:" << e->getInstant().toString() << e->getValue()->getValue().toDouble();
1307                                 }
1308                         }
1309                 }
1310                 
1311         }
1312         
1313         tsResponse->destroyCascade();
1314         return true;
1315 }
1316
1317 bool notificationTest()
1318 {
1319         QString myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
1320
1321         Notification* notification = NotificationFactory::create(myId);
1322         Activity* activity = new Activity();
1323         Output* output = new Output();
1324         SystemOfInterest* soi = new SystemOfInterest();
1325         SystemOfInterest* capacitySoi = new SystemOfInterest();
1326         Address* address = new Address();
1327         Velocity* speed = new Velocity();
1328         Direction* direction = new Direction();
1329         Capacity* capacity = new Capacity();
1330         PhysicalEntity* vehicle = new PhysicalEntity();
1331
1332         soi->addType(RESOURCE__CAR);
1333         soi->setSameAs(myId);
1334         soi->setName("Simulated vehicle 1");
1335
1336         capacitySoi->addType(RESOURCE__BATTERY);
1337         vehicle->addType(RESOURCE__CAR);
1338         output->addCategory(RESOURCE__OBSERVATION);
1339
1340         activity->addOutput(output);
1341         notification->addActivity(activity);
1342         output->setSystemOfInterest(soi);
1343         soi->setRealizedBy(vehicle);
1344         vehicle->setVelocity(speed);
1345         vehicle->setAddress(address);
1346         vehicle->setDirection(direction);
1347         vehicle->addCapacity(capacity);
1348
1349         capacity->setSystemOfInterest(capacitySoi);
1350         capacity->setQuantity(RESOURCE__POWER);
1351         capacity->setUnit(RESOURCE__KILOWATT);
1352         capacity->setMaximum(new Variant(2000));
1353         capacity->setValue(new Variant(1000));
1354
1355         vehicle->setCoordinates(new Coordinates(60.4, 30.2));
1356         direction->setBearing(new ValueObject(NS__UNIT + "DegreeAngle", new Variant(30)));
1357         speed->setGroundSpeed(new ValueObject(NS__UNIT + "MeterPerSecond", new Variant(10)));
1358
1359         QString payload = Tools::toString(notification, SERIALIZATION__TURTLE);
1360
1361         qDebug() << "Serialized:";
1362         printf("%s\n", payload.toLatin1().data());
1363         notification->destroyCascade();
1364
1365         Obj* parsedObj = Tools::fromStringAsObj(payload);
1366         if (Notification* parsedNotification = dynamic_cast<Notification*>(parsedObj)) {
1367                 QString reserialized = Tools::toString(parsedNotification, SERIALIZATION__TURTLE);
1368                 qDebug() << "Re-Serialized:";
1369                 printf("%s\n", reserialized.toLatin1().data());
1370         }
1371         parsedObj->destroyCascade();
1372
1373         return true;
1374 }
1375
1376 bool offeringTest()
1377 {
1378         QString myId = "http://seasdemos.asema.com/csharp/controlcommandsender/Cabcd";
1379         QString offerName = "Test offer";
1380         QString offerDescription = "Some offer description";
1381
1382         Activity* activity = new Activity();
1383         Offering* offering = new Offering(myId + "/" + SmartAPICrypto::generate16ByteCryptoRandomString(), offerName, offerDescription);
1384         offering->setBusinessFunction(RESOURCE__SELL);
1385
1386         UnitPriceSpecification* priceSpecification1 = new UnitPriceSpecification();
1387         priceSpecification1->setCurrency("EUR");
1388         priceSpecification1->setCurrencyValue(10.0);
1389         priceSpecification1->setValidThrough(QDateTime::currentDateTime());
1390         UnitPriceSpecification* priceSpecification2 = new UnitPriceSpecification();
1391         priceSpecification2->setCurrency("EUR");
1392         priceSpecification2->setCurrencyValue(12.0);
1393         priceSpecification2->setValidThrough(QDateTime::currentDateTime());
1394
1395         offering->addPriceSpecification(priceSpecification1);
1396         offering->addPriceSpecification(priceSpecification2);
1397
1398         SomeItems* items = new SomeItems(RESOURCE__REQUEST, "Service request", "Any kind of service request.", myId);
1399         offering->addIncludes(items);
1400         activity->addOffering(offering);
1401         QString payload = Tools::toString(activity, SERIALIZATION__TURTLE);
1402
1403         qDebug() << "Serialized:";
1404         printf("%s\n", payload.toLatin1().data());
1405         activity->destroyCascade();
1406
1407         Obj* parsedObj = Tools::fromStringAsObj(payload);
1408         if (Activity* parsedActivity = dynamic_cast<Activity*>(parsedObj)) {
1409                 QString reserialized = Tools::toString(parsedActivity, SERIALIZATION__TURTLE);
1410                 qDebug() << "Re-Serialized:";
1411                 printf("%s\n", reserialized.toLatin1().data());
1412         }
1413         parsedObj->destroyCascade();
1414         return true;
1415 }
1416
1417 bool listOfMapsTest()
1418 {
1419         Activity* a = new Activity();
1420         Input* i = new Input();
1421         Output* o = new Output();
1422         a->addInput(i);
1423         a->addOutput(o);
1424
1425         // Input
1426         QList<Map*> controllable_appliances;
1427         QList<Map*> controllable_works;
1428         
1429         Map* works1 = new Map();
1430         works1->insert("EarlyStartPeriod", 2147483647);
1431         works1->insert("LateStopPeriod", 2147483647);
1432         works1->insert("WorkDuration", 2147483647);
1433
1434         Map* appliance1 = new Map();
1435         appliance1->insert("Active", 4);
1436         appliance1->insert("ConsumptionRate", 1.267);
1437         appliance1->insert("Name", "String content");
1438         appliance1->add("ControllableWorks", works1); //controllable_works);
1439         
1440         //controllable_works.append(works1);
1441         controllable_appliances.append(appliance1);
1442         i->add("ControllableAppliances", controllable_appliances);
1443
1444         // Output
1445         QList<Map*> controllable_appliance_result;
1446         QList<Map*> controllable_appliance_work_result;
1447
1448         Map* appliance_result_1 = new Map();
1449         Map* work_result_1 = new Map();
1450         Map* usage_information = new Map();
1451         
1452         appliance_result_1->insert("Name", "Appliance result string");
1453         usage_information->insert("StartPeriod", 2147483647);
1454         usage_information->insert("StopPeriod", 2147483647);
1455         usage_information->insert("WorkDuration", 2147483647);
1456         work_result_1->add("UsageInformation", usage_information);
1457         controllable_appliance_work_result.append(work_result_1);
1458         appliance_result_1->insert("ControllableWorkResult", controllable_appliance_work_result);
1459         
1460         //QList<Map*> period_consumptions;
1461         Map* period_1 = new Map();
1462         period_1->insert("Period", 2147483647);
1463         period_1->insert("Value", 1.26743);
1464         //period_consumptions.append(period_1);
1465         work_result_1->add("PeriodConsumption", period_1); //period_consumptions);
1466         
1467         controllable_appliance_result.append(appliance_result_1);
1468         o->add("ControllableApplianceResult", controllable_appliance_result);
1469         qDebug() << "Start serializing...";
1470
1471         QString serialized = Tools::toString(a, SERIALIZATION__TURTLE);
1472         qDebug() << "Serialized:\n";
1473         printf("\n%s\n", serialized.toUtf8().constData());
1474         a->destroyCascade();
1475         
1476         qDebug() << "Start parsing...";
1477         Obj* a_parsed = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
1478
1479         if (a_parsed != NULL) {
1480                 QString reserialized = Tools::toString(a_parsed, SERIALIZATION__TURTLE);
1481
1482                 qDebug() << "----";
1483                 qDebug() << "Re-serialized:";
1484                 printf("\n%s\n", reserialized.toUtf8().constData());
1485                 a_parsed->destroyCascade();
1486                 return true;
1487         } else {
1488                 qDebug() << "Parsing failed.";
1489                 return false;
1490         }
1491 }
1492
1493 //bool chargePlanRegistrationTest()
1494 //{
1495 //      QString serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
1496 //      QString serverName = "A sample charging plan calculation service";
1497
1498 //      Service* service = new Service(serverIdentity);
1499
1500 //      // Service metadata
1501 //      Organization* owner = new Organization();
1502 //      Address* acmeAddress = new Address();
1503 //      InterfaceAddress* iface = new InterfaceAddress();
1504
1505 //      iface->setHost("www.acme.com");
1506 //      iface->setScheme("https");
1507 //      iface->setPath("/seas/v1.0e1.0/access");
1508 //      acmeAddress->setStreetAddress("Giant Rubber Band Street");
1509 //      acmeAddress->setZipCode("12345");
1510 //      acmeAddress->setCity("Fairfield, New Jersey");
1511 //      owner->setName("Acme Industries");
1512 //      owner->setAddress(acmeAddress);
1513
1514 //      service->addInterface(iface);
1515 //      service->addOwner(owner);
1516 //      service->setName(serverName);
1517 //      service->setDescription("A charging plan service that supplies the available energy for charging in timeslots at a charging point.");
1518 //      service->addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
1519
1520
1521 //      // API payload data
1522 //      Activity* a = new Activity();
1523 //      Input* i = new Input();
1524 //      Output* o = new Output();
1525 //      a->addOutput(o);
1526 //      a->addInput(i);
1527 //      service->addCapability(a);
1528
1529 //      // Input
1530 //      Map* charge_need = new Map();
1531 //      charge_need->insert("Energy", Factory::createValueObject(NS__UNIT + "KilowattHour", "Total amount of energy requested to complete the charge."));
1532 //      charge_need->insert("PowerMax", Factory::createValueObject(NS__UNIT + "Watt", "Maximum allowed instant power for charging the vehicle."));
1533 //      charge_need->insert("PowerMin", Factory::createValueObject(NS__UNIT + "Watt", "Minumum allowed instant power for charging the vehicle."));
1534 //      charge_need->insert("Priority", new Obj(DATATYPE__INTEGER));
1535 //      charge_need->insert("Type", new Enumeration("Immediate", "Delayed"));
1536 //      TemporalContext* tci = new TemporalContext();
1537 //      tci->setDescription("The desired schedule at which the charging should take place (start (optional) and end)");
1538 //      charge_need->insert("Schedule", tci);
1539 //      i->add("ChargingNeed", charge_need);
1540
1541 //      // Output
1542 //      Map* charge_plan = new Map();
1543 //      QList<Map*> orders;
1544 //      Map* order = new Map();
1545 //      TemporalContext* tco = new TemporalContext();
1546 //      tco->setDescription("The start and end times of this charging slot.");
1547 //      order->insert("Schedule", tco);
1548 //      order->insert("Power", Factory::createValueObject(NS__UNIT + "Watt", "The instant power supplied in this slot."));
1549 //      orders.append(order);
1550 //      charge_plan->insert("Orders", orders);
1551 //      o->add("ChargingPlan", charge_plan);
1552
1553 //      RegistrationAgent* agent = new RegistrationAgent(serverIdentity);
1554 //      QString payload = agent->generateRegistrationMessage(service);
1555 //      printf("%s\n", payload.toUtf8().constData());
1556 //      service->destroyCascade();
1557 //    delete agent;
1558
1559 //    return true;
1560 //}
1561
1562 EVP_PKEY* getPemPublicKey(QString fileName)
1563 {
1564         return SmartAPICrypto::loadPemPublicKey(fileName);
1565 }
1566
1567 EVP_PKEY* getPemPrivateKey(QString fileName)
1568 {
1569         return SmartAPICrypto::loadPemPrivateKey(fileName);
1570 }
1571
1572 Service* createSampleRegistrationEntity(QString serverIdentity)
1573 {
1574         QString serverName = "A C++ sample route energy calculation service";
1575
1576         Service* service = new Service(serverIdentity);
1577
1578         // Service metadata
1579         Organization* owner = new Organization();
1580         Address* acmeAddress = new Address();
1581         InterfaceAddress* iface = new InterfaceAddress();
1582
1583         iface->setHost("www.acme.com");
1584         iface->setScheme("https");
1585         iface->setPath("/seas/v1.0e1.0/access");
1586         acmeAddress->setStreetAddress("Giant Rubber Band Street");
1587         acmeAddress->setZipCode("12345");
1588         acmeAddress->setCity("Fairfield, Cee");
1589         owner->setName("Acme Industries");
1590         owner->setAddress(acmeAddress);
1591
1592         service->addInterface(iface);
1593         service->addOwner(owner);
1594         
1595         
1596         service->setName(serverName);
1597         service->setDescription("A route calculation service that in addition to length and driving time calculates the amount of energy consumed in the battery. Takes as parameters various efficiency factors such as weight and drag.");
1598         service->addWebsite("http://www.acme.com/acmeoptimizers/roadrunner/beep/beep");
1599
1600         // API payload data
1601         Activity* a = new Activity();
1602         Input* i = new Input();
1603         Output* o = new Output();
1604         a->addOutput(o);
1605         a->addInput(i);
1606         service->addCapability(a);
1607
1608         PhysicalEntity* car = new PhysicalEntity();
1609         car->setWeight(Factory().createValueObject(NS__UNIT + "Kilogram", "Vehicle's weight without any consumables or passengers."));
1610         car->add("frontalAerodynamicCoefficient", Factory::createValueObject(NS__UNIT + "SquareMeter", "Product of vehicle's frontal area and aerodynamic coefficient"));
1611         car->add("tireRollingResistanceCoefficient", Factory::createValueObject(new Obj(DATATYPE__INTEGER), "Vehicle's tire rolling resistance coefficient, in interval ]0, 1["));
1612         car->add("gearEfficiencyCoefficient", Factory::createValueObject("Vehicle's efficiency coefficient between engine and gear, in interval ]0, 1["));
1613         car->add("batteryCapacity", Factory::createValueObject(NS__UNIT + "KilowattHour", "Vehicle's capacity of the battery (enter only if electric vehicle or hybrid rechargeable, 0 otherwise"));
1614         car->add("extraLoadWeight", Factory::createValueObject(NS__UNIT + "Kilogram", "Vehicle's extra load (consumables and passengers weight)"));
1615         car->add("auxiliaryEquipmentConsumption", Factory::createValueObject(NS__UNIT + "Watt", "Vehicle's instantaneous auxiliary equipments consumption"));
1616         car->add("maximumAcceleration", Factory::createValueObject(NS__UNIT + "MeterPerSecondSquared", "Maximum acceleration (> 0.1), based on vehicle's acceleration capacity and expected driving behavior"));
1617         car->add("maximumDeceleration", Factory::createValueObject(NS__UNIT + "MeterPerSecondSquared", "Maximum deceleration (< -0.1), based on vehicle's braking capacity and expected driving behavior"));
1618         i->add("vehicleData", car);
1619
1620         TemporalContext* tc = new TemporalContext();
1621         Velocity* averageVelocity = new Velocity();
1622         Route* route = new Route();
1623
1624         tc->setDescription("The timespan estimated for traveling the route.");
1625         averageVelocity->setDescription("Estimated average speed for the travel.");
1626
1627         averageVelocity->setGroundSpeed(Factory::createValueObject(NS__UNIT + "KilometerPerHour", "Velocity component in relation to road surface."));
1628         
1629         route->setLength(Factory::createValueObject(NS__UNIT + "Kilometer", "Total length of the calculated route."));
1630         route->setEnergyConsumption(Factory::createValueObject(NS__UNIT + "KilowattHour", "Total energy consumed in driving the route."));
1631         route->setAverageVelocity(averageVelocity);
1632         route->setDuration(tc);
1633
1634         o->add("routeData", route);
1635         
1636         return service;
1637 }
1638
1639 //bool encryptedRegistrationTest()
1640 //{
1641 //      QString serverIdentity = "http://seasexamples.asema.com/api/Ctestserver";
1642 //      QString serverName = "A sample charging plan calculation service";
1643
1644 //      EVP_PKEY* pubKey = getPemPublicKey("../../Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
1645 //      EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
1646
1647 //      Service* service = createSampleRegistrationEntity(serverIdentity);
1648
1649 //      RegistrationAgent agent(serverIdentity);
1650
1651 //      QByteArray symKey;
1652 //      QString payload = agent.generateEncryptedRegistrationMessage(pubKey, service, &symKey);
1653 //      printf("%s\n", payload.toUtf8().constData());
1654         
1655 //      //printf("%s\n", payload.toUtf8().data());
1656 //      QString decrypted = SmartAPICrypto::asymmetricDecrypt(privKey, payload, &symKey);
1657 //      printf("Decrypted len: %d\n", decrypted.length());
1658 //      printf("%s\n", decrypted.toUtf8().data());
1659         
1660 //      qDebug() << "------";
1661 //      QString ct = SmartAPICrypto::symmetricEncrypt((unsigned char*)symKey.constData(), decrypted);
1662 //      printf("%s\n", ct.toUtf8().data());
1663 //      QString pt = SmartAPICrypto::symmetricDecrypt((unsigned char*)symKey.constData(), ct);
1664 //      printf("%s\n", pt.toUtf8().data());
1665         
1666 //      service->destroyCascade();
1667 //      EVP_PKEY_free(pubKey);
1668 //      EVP_PKEY_free(privKey);
1669
1670 //      return true;
1671 //}
1672
1673 bool gatewayRegistrationTest()
1674 {
1675         QString myIdentity = "http://www.itron.com";
1676         QString gatewayIdentity = "http://itron.ilm.net/core/Gateway153";
1677         QString acMeterIdentity = "http://itron.ilm.net/core/ACmeter2493";
1678         QString dcMeterIdentity = "http://itron.ilm.net/core/DCmeter2494";
1679         
1680         Device* gateway = new Device(gatewayIdentity);
1681         Device* acMeter = new Device(acMeterIdentity);
1682         Device* dcMeter = new Device(dcMeterIdentity);
1683         
1684         Organization* gatewayOwner = new Organization();
1685         Organization* acOwner = new Organization();
1686         Organization* dcOwner = new Organization();
1687         
1688         gateway->setName("Itron gateway");
1689         gateway->addManagedEntity(acMeter);
1690         gateway->addManagedEntity(dcMeter);
1691
1692         acMeter->setName("AC Electricity Smart Meter");
1693         dcMeter->setName("DC Electricity Smart Meter");
1694         
1695         gatewayOwner->setName("Itron");
1696         acOwner->setName("Itron");
1697         dcOwner->setName("Itron");
1698         
1699         Address* gatewayAddress = new Address();
1700         Address* acAddress = new Address();
1701         Address* dcAddress = new Address();
1702         
1703         gatewayAddress->setCity("Issy Les Moulineaux");
1704         acAddress->setCity("Issy Les Moulineaux");
1705         dcAddress->setCity("Issy Les Moulineaux");
1706         gatewayAddress->setCountry("France");
1707         acAddress->setCountry("France");
1708         dcAddress->setCountry("France");
1709         
1710         gateway->setAddress(gatewayAddress);
1711         acMeter->setAddress(acAddress);
1712         dcMeter->setAddress(dcAddress);
1713         gateway->addOwner(gatewayOwner);
1714         acMeter->addOwner(acOwner);
1715         dcMeter->addOwner(dcOwner);
1716         
1717         InterfaceAddress* gatewayIface = new InterfaceAddress();
1718         InterfaceAddress* acIface = new InterfaceAddress();
1719         InterfaceAddress* dcIface = new InterfaceAddress();
1720         
1721         gatewayIface->setHost("itron.ilm.net");
1722         acIface->setHost("itron.ilm.net");
1723         dcIface->setHost("itron.ilm.net");
1724         
1725         gatewayIface->setScheme("core");
1726         acIface->setScheme("core");
1727         dcIface->setScheme("core");
1728         
1729         gatewayIface->setPort(2000);
1730         acIface->setPort(2000);
1731         dcIface->setPort(2000);
1732         
1733         gatewayIface->setPath("/core/Gateway153");
1734         acIface->setPath("/core/ACmeter2493");
1735         dcIface->setPath("/core/DCmeter2494");
1736         
1737         gateway->addInterface(gatewayIface);
1738         acMeter->addInterface(acIface);
1739         dcMeter->addInterface(dcIface);
1740
1741         
1742         // add the api to the gateway
1743         Activity* activity = new Activity();
1744
1745         // input for selecting which output values (quantities and unit) are returned
1746         Input* i = new Input();
1747         Obj* serial = new Obj(DATATYPE__INTEGER);
1748         serial->setDescription("The meter serial number, as shown by the label on the meter");
1749         i->add("meterSerialNumber", serial);
1750         activity->addInput(i);
1751         
1752         Output* o = new Output();
1753         o->add(NS__SMARTAPI + "PowerConsumption", Factory::createValueObject(NS__UNIT + "Watt", "Power consumption."));
1754         o->add(NS__SMARTAPI + "AccumulatedConsumption", Factory::createValueObject(NS__UNIT + "WattHour", "Accumulated energy consumption."));
1755         activity->addOutput(o);
1756         gateway->addCapability(activity);
1757
1758         QString payload = Tools::toString(gateway, SERIALIZATION__TURTLE);
1759
1760         qDebug() << "Serialized:";
1761         printf("%s\n", payload.toLatin1().data());
1762         gateway->destroyCascade();
1763         
1764         Obj* a_parsed = Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
1765
1766         if (a_parsed != NULL) {
1767                 QString reserialized = Tools::toString(a_parsed, SERIALIZATION__TURTLE);
1768
1769                 qDebug() << "----";
1770                 qDebug() << "Re-serialized:";
1771                 printf("\n%s\n", reserialized.toUtf8().constData());
1772                 a_parsed->destroyCascade();
1773         } else {
1774                 qDebug() << "Parsing failed.";
1775                 return false;
1776         }
1777         
1778         // registrate
1779         //RegistrationAgent* agent = new RegistrationAgent(myIdentity);
1780         // Note: this will bind the entities to the agent which in turn will delete them
1781         //agent->addEntity(gateway);
1782         //agent->addEntity(acMeter);
1783         //agent->addEntity(dcMeter);
1784         
1785         //agent->makeRegistration();
1786         //QString payload = agent->generateRegistrationMessage();
1787         //printf("%s\n", payload.toUtf8().constData());
1788
1789         //delete agent;
1790         return true;
1791 }
1792
1793 bool faultyIdTest()
1794 {
1795         Activity* a1 = new Activity("http://act.com");
1796         a1->addInput(new Input());
1797
1798         // NOTE: all property lists of a2 are now considered copies of a1
1799         // Any objects put into a2 lists will not be deleted as it is assumed
1800         // that a1 will delete them.
1801         Activity* a2 = new Activity(a1);
1802
1803         Entity* e1 = new Entity("http://e1.com");
1804         e1->addCapability(a1);
1805         Entity* e2 = new Entity("http://e2.com");
1806         e2->addCapability(a1);
1807         Entity* e3 = new Entity("http://e3.com");
1808         e3->addCapability(a1);
1809         e3->addCapability(a2);
1810         
1811         Request* r = new Request();
1812
1813         // Adding entities into a2 instead of a1 would now cause a memory leak
1814         a1->addEntity(e1);
1815         a1->addEntity(e2);
1816         a1->addEntity(e3);
1817         r->addActivity(a1);
1818         r->addActivity(a2);
1819         QString payload = Tools::toString(r, SERIALIZATION__TURTLE);
1820
1821         qDebug() << "Serialized:";
1822         printf("%s\n", payload.toLatin1().data());
1823         r->destroyCascade();
1824
1825         return true;
1826 }
1827
1828 bool routeRequestTest()
1829 {
1830         QString myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1831
1832         Request* request = RequestFactory::create(myId);
1833         request->setMethod(NS__SMARTAPI + "Read");
1834
1835         Activity* activity = new Activity();
1836         Input* input = new Input();
1837
1838         SystemOfInterest* sys_of_interest = new SystemOfInterest();
1839         sys_of_interest->setType(NS__SMARTAPI + "ChargingStation");
1840         input->setSystemOfInterest(sys_of_interest);
1841
1842         Coordinates* coordinates = new Coordinates(41.3746157, 2.1428249);
1843
1844         input->add("search_coordinates", new Variant(coordinates));
1845         input->add("max_distance", new Variant(100));
1846
1847         activity->addInput(input);
1848         request->addActivity(activity);
1849
1850         QString payload = Tools::toString(request, SERIALIZATION__TURTLE);
1851         request->destroyCascade();
1852         
1853         
1854         QUrl serviceUrl = QUrl("http://127.0.0.1:8099/RoutingService/seas/v1.0/fetchData/");
1855
1856         QNetworkAccessManager *networkManager = new QNetworkAccessManager();
1857         QEventLoop postWaitLoop;
1858         
1859         QNetworkRequest nrequest(serviceUrl);
1860         nrequest.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
1861         nrequest.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("1"));
1862         nrequest.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("fetchData"));
1863         nrequest.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
1864         
1865         QNetworkReply* reply = networkManager->post(nrequest, payload.toUtf8());
1866         QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
1867         postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
1868         
1869         QByteArray result = reply->readAll();
1870         reply->deleteLater();
1871         networkManager->deleteLater();
1872
1873         //printf("%s\n", result.data());
1874         
1875         QVariantMap rm;
1876         QVariantList resultList;
1877         Obj* o = Tools::fromStringAsObj(QString(result));
1878         if (Response* r = dynamic_cast<Response*>(o)) {
1879                 
1880                         if (r->hasActivity()) {
1881                                 Activity* a = r->getActivities().at(0);
1882                                 if (a->hasOutput()) {
1883                                         Output* o = a->getOutputs().at(0);
1884                                         QList<GraphItem*> results = o->getAll("result")->toQList();
1885                                         for (int i = 0; i < results.length(); i++) {
1886                                                 QVariantMap result;
1887                                                 float price = 0;
1888                                                 QString station_id = "";
1889                                                 QString requester_id = "";
1890                                                 float distance = 0;
1891                                                 QString time_of_arrival = "";
1892                                                 float latitude = 0;
1893                                                 float longitude = 0;
1894                                                 float energy_use = 0;
1895                                                 QVariantList route;
1896                                                 
1897                                                 Map* m = (Map*)((Variant*)results.at(i))->asObj();
1898                                                 if (m) {
1899                                                         Variant* vo_i = m->get("price");
1900                                                         Variant* si_i = m->get("station_id");
1901                                                         Variant* ri_i = m->get("requester_id");
1902                                                         Variant* di_i = m->get("distance");
1903                                                         Variant* co_i = m->get("coordinates");
1904                                                         Variant* ro_i = m->get("route");
1905                                                         Variant* ta_i = m->get("time_of_arrival");
1906
1907                                                         if (vo_i != NULL && vo_i->asObj() != NULL) price = ((ValueObject*)vo_i->asObj())->getValue()->asFloat();
1908                                                         if (si_i != NULL && si_i->asObj() != NULL) station_id = ((SystemOfInterest*)si_i->asObj())->getSameAs()->getIdentifierUri();
1909                                                         if (ri_i != NULL) requester_id = ri_i->asString();
1910                                                         if (di_i != NULL && di_i->asObj() != NULL) distance = ((ValueObject*)di_i->asObj())->getValue()->asFloat();
1911                                                         if (ta_i != NULL) time_of_arrival = ta_i->asString();
1912                                                         if (co_i != NULL) {
1913                                                                 Coordinates* c = (Coordinates*)co_i->asObj();
1914                                                                 if (c != NULL) {
1915                                                                         latitude = c->getLatitude();
1916                                                                         longitude = c->getLongitude();
1917                                                                 }
1918                                                         }
1919                                                         if (ro_i != NULL) {
1920                                                                 Route* r = (Route*)ro_i->asObj();
1921                                                                 if (r != NULL) {
1922                                                                         PropertyList<Coordinates*> cl = r->getRoutePoints();
1923                                                                         for (int j = 0; j < cl.length(); j++) {
1924                                                                                 Coordinates* cc = cl.at(j);
1925                                                                                 QVariantMap cm;
1926                                                                                 cm.insert("latitude", cc->getLatitude());
1927                                                                                 cm.insert("longitude", cc->getLongitude());
1928                                                                                 route << cm;
1929                                                                         }
1930                                                                 }
1931                                                         }
1932                                                 } else {
1933                                                         qDebug() << "The result map from Routing Service is NULL";
1934                                                         return false;
1935
1936                                                 }
1937                                                 result.insert("price", price);
1938                                                 result.insert("station_id", station_id);
1939                                                 result.insert("requester_id", requester_id);
1940                                                 result.insert("distance", distance);
1941                                                 result.insert("time_of_arrival", time_of_arrival);
1942                                                 result.insert("latitude", latitude);
1943                                                 result.insert("longitude", longitude);
1944                                                 result.insert("energy_use", energy_use);
1945                                                 result.insert("route", route);
1946                                                 resultList.append(result);
1947                                         }
1948                                 }
1949                 }
1950         } 
1951         o->destroyCascade();
1952         //qDebug() << resultList;
1953         rm.insert("results", resultList);
1954
1955         return true;
1956 }
1957
1958 //bool chargePlanFetchTest()
1959 //{
1960 //      QString myId = "http://seasdemos.asema.com/cplusplus/controlcommandsender/Cabcd";
1961
1962 //      Request* request = RequestFactory::create(myId);
1963 //      request->setMethod(NS__SMARTAPI + "Read");
1964         
1965 //      Activity* activity = new Activity();
1966 //      request->addActivity(activity);
1967
1968 //      Input* powerMaxSiteInput = new Input();
1969 //      powerMaxSiteInput->setName("PMaxSite");
1970         
1971 //      Input* needsInput = new Input();
1972 //      needsInput->setName("Needs");
1973
1974 //      activity->addInput(powerMaxSiteInput);
1975 //      activity->addInput(needsInput);
1976
1977                 
1978 //      // Maximul instant Power limit on the site
1979 //      ValueObject* powerMaxSite = new ValueObject();
1980 //      powerMaxSite->setQuantity(RESOURCE__POWER);
1981 //      powerMaxSite->setName("PMaxSite");
1982 //      powerMaxSite->setUnit(RESOURCE__KILOWATT);
1983 //      powerMaxSite->setValue(new Variant(40));
1984 //      powerMaxSiteInput->add("PMaxSite", powerMaxSite);
1985
1986 //      // chargeNeeds list
1987
1988 //      QList<Map*> needs;
1989         
1990 //      Map* need = new Map();
1991
1992 //      // Charge ID
1993 //      need->insert("ChargeID", new Variant(145));
1994
1995 //      ValueObject* energy = new ValueObject();
1996 //      energy->setQuantity(RESOURCE__ELECTRICENERGY);
1997 //      energy->setUnit(RESOURCE__KILOWATTHOUR);
1998 //      energy->setValue(new Variant(600));
1999 //      need->insert("Energy", energy);
2000
2001 //      ValueObject* powerMin = new ValueObject();
2002 //      powerMin->setQuantity(RESOURCE__POWER);
2003 //      powerMin->setUnit(RESOURCE__KILOWATT);
2004 //      powerMin->setValue(new Variant(30));
2005 //      need->insert("PowerMin", powerMin);
2006
2007 //      ValueObject* powerMax = new ValueObject();
2008 //      powerMax->setQuantity(RESOURCE__POWER);
2009 //      powerMax->setUnit(RESOURCE__KILOWATT);
2010 //      powerMax->setValue(new Variant(1000));
2011 //      need->insert("PowerMax", powerMax);
2012
2013 //      // Schedule
2014 //      QDateTime start = QDateTime::currentDateTime();
2015 //      QDateTime end = start.addSecs(3600);
2016         
2017 //      TemporalContext* tco = new TemporalContext();
2018 //      tco->setStart(start);
2019 //      tco->setEnd(end);
2020 //      need->insert("Schedule", tco);
2021
2022 //      need->insert("Priority", new Variant(1));
2023 //      need->insert("Type", new Variant("Delayed"));
2024
2025 //      needs.append(need);
2026
2027 //      needsInput->add("Needs", needs);
2028
2029 //      QString payload = Tools::toString(request, SERIALIZATION__TURTLE);
2030 //      request->destroyCascade();
2031         
2032 //      QUrl serviceUrl = QUrl("http://seas.asema.com:2683/seas/v1.0e1.0/access/");
2033
2034 //      QNetworkAccessManager *networkManager = new QNetworkAccessManager();
2035 //      QEventLoop postWaitLoop;
2036         
2037 //      QNetworkRequest nrequest(serviceUrl);
2038 //      nrequest.setHeader(QNetworkRequest::ContentTypeHeader, CONTENT_TYPE__TURTLE);
2039 //      nrequest.setRawHeader(QByteArray("X-SmartAPI-CallId"), QByteArray("1"));
2040 //      nrequest.setRawHeader(QByteArray("X-SmartAPI-Method"), QByteArray("fetchData"));
2041 //      nrequest.setRawHeader(QByteArray("Accept"), QByteArray(CONTENT_TYPE__TURTLE));
2042         
2043 //      QNetworkReply* reply = networkManager->post(nrequest, payload.toUtf8());
2044 //      QObject::connect( reply, SIGNAL(finished()), &postWaitLoop, SLOT(quit()));
2045 //      postWaitLoop.exec( QEventLoop::ExcludeUserInputEvents );
2046         
2047 //      QByteArray result = reply->readAll();
2048 //      reply->deleteLater();
2049 //      networkManager->deleteLater();
2050
2051         
2052 //      printf("---- CHARGE PLAN ----\n%s\n-------------\n", result.data());
2053         
2054 //      QVariantMap rm;
2055 //      QVariantList resultList;
2056 //      Obj* o = Tools::fromStringAsObj(QString(result));
2057 //      if (Response* r = dynamic_cast<Response*>(o)) {
2058 //              if (r->hasActivity()) {
2059 //                      Activity* a = r->getActivities().at(0);
2060 //                      if (a->hasOutput()) {
2061 //                              Output* ou = a->getOutputs().at(0);
2062 //                              QList<GraphItem*> plans = ou->getAll("ChargingPlan")->toQList();
2063 //                              for (int pi = 0; pi < plans.length(); pi++) {
2064 //                                      Variant* plan = (Variant*)plans.at(pi);
2065 //                                      Map* planMap = (Map*)plan->asObj();
2066 //                                      Variant* orders =  planMap->get("Orders");
2067 //                                      QList<Variant*> orderList = orders->asList();
2068 //                                      for (int oi = 0; oi < orderList.length(); oi++) {
2069 //                                              QVariantMap plan;
2070 //                                              Variant* order = orderList.at(oi);
2071 //                                              Map* orderMap = (Map*)order->asObj();
2072 //                                              ValueObject* power = (ValueObject*)orderMap->get("Power")->asObj();
2073 //                                              TemporalContext* tco = (TemporalContext*)orderMap->get(NS__SMARTAPI + "temporalContext")->asObj();
2074                                         
2075 //                                              plan.insert("start", tco->getStart());
2076 //                                              plan.insert("end", tco->getEnd());
2077 //                                              plan.insert("power", power->getValue()->getValue());
2078 //                                              plan.insert("power_unit", power->getUnit());
2079 //                                              resultList << plan;
2080 //                                      }
2081 //                              }
2082 //                      }
2083 //              }
2084 //      } else {
2085 //              return false;
2086 //      }
2087 //      o->destroyCascade();
2088 //      qDebug() << resultList;
2089         
2090 //      return true;
2091 //}
2092
2093 bool availabilityTest()
2094 {
2095         // Temporal availability
2096         Availability* a1 = new Availability();
2097         TemporalContext* tcx = new TemporalContext();
2098         tcx->setStart(QDateTime::currentDateTime());
2099         tcx->setEnd(QDateTime::currentDateTime());
2100         tcx->setDuring(RESOURCE__WEEKDAY);
2101         a1->setTemporalContext(tcx);
2102         printf("%s\n", Tools::toString(a1, SERIALIZATION__TURTLE).toUtf8().constData());
2103         
2104         // Temporal availability
2105         Availability* a2 = new Availability();
2106         TemporalContext* tcx2 = new TemporalContext();
2107         tcx2->setStart(QDateTime::currentDateTime());
2108         tcx2->setEnd(QDateTime::currentDateTime());
2109         a2->setTemporalContext(tcx2);
2110         //printf("%s\n", Tools::toString(a2, SERIALIZATION__TURTLE).toUtf8().constData());
2111         
2112         // Property based availability (distance)
2113         Availability* a3 = new Availability();
2114         Ring* ring = new Ring();
2115         ring->setCoordinates(60.1, 24.1);
2116         ring->setMaxRadiusInKilometers(10);
2117         a3->setRing(ring);
2118         printf("%s\n", Tools::toString(a3, SERIALIZATION__TURTLE).toUtf8().constData());
2119         
2120         // Property based availability (address)
2121         Availability* a4 = new Availability();
2122         Address* addr = new Address();
2123         addr->setCountry("Finland");
2124         addr->setCity("Espoo");
2125         a4->setAddress(addr);
2126         printf("%s\n", Tools::toString(a4, SERIALIZATION__TURTLE).toUtf8().constData());
2127         
2128         // Property based availability (system state)
2129         Availability* a5 = new Availability();
2130         a5->setProperty(PROPERTY__SYSTEMSTATE);
2131         // FIXME: a5->addValue("away");
2132         // FIXME: a5->addValue("away long");
2133         printf("%s\n", Tools::toString(a5, SERIALIZATION__TURTLE).toUtf8().constData());
2134         
2135         // Property based availability (capacity)
2136         Availability* a6 = new Availability();
2137         a6->setProperty(PROPERTY__CAPACITY);
2138         a6->setIsControlledBy("http://acme.com/backend/CentityId");
2139         // system of interest / capacity id can be left out if there is only one capacity
2140         a6->setSystemOfInterestWithSameAs("http://acme.com/backend/CcapacityId");
2141         a6->setUnit(RESOURCE__PERCENT);
2142         a6->setMinimum(new Variant(40));
2143         printf("%s\n", Tools::toString(a6, SERIALIZATION__TURTLE).toUtf8().constData());
2144         
2145         // Property based availability (user)
2146         Availability* a7 = new Availability();
2147         a7->addPersonByUsername("seas");
2148         a7->addPersonByUsername("admin");
2149         printf("%s\n", Tools::toString(a7, SERIALIZATION__TURTLE).toUtf8().constData());
2150         
2151         // Property based availability (priority)
2152         Availability* a8 = new Availability();
2153         a8->setPriorityInPercents(70);
2154         printf("%s\n", Tools::toString(a8, SERIALIZATION__TURTLE).toUtf8().constData());
2155
2156         a1->destroyCascade();
2157         a2->destroyCascade();
2158         a3->destroyCascade();
2159         a4->destroyCascade();
2160         a5->destroyCascade();
2161         a6->destroyCascade();
2162         a7->destroyCascade();
2163         a8->destroyCascade();
2164
2165         return true;
2166 }
2167
2168 bool hugeDataTest()
2169 {
2170         qDebug() << "Not implemented yet";
2171         return false;
2172 }
2173
2174 bool keyServerTest()
2175 {
2176         QString content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2177         QString keyId = "http://www.acme.com/services/abcd/";
2178         QString publicKeyServer = "http://127.0.0.1:11371";
2179         EVP_PKEY* downloadedKey = SmartAPICrypto::downloadPublicKey(keyId, publicKeyServer);
2180         EVP_PKEY* pubKey = getPemPublicKey("../../Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
2181         EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2182
2183         QString signature = SmartAPICrypto::sign(privKey, content);
2184         qDebug() << "new signature" << signature;
2185         bool verified = SmartAPICrypto::verifySignature(signature, pubKey, content);
2186
2187         qDebug() << "Signature verification, key on disk " << (verified ? "successful" : "failed");
2188         if (!verified) {
2189                 return false;
2190         }
2191
2192         verified = SmartAPICrypto::verifySignature(signature, downloadedKey, content);
2193         qDebug() << "Signature verification, downloaded key " << (verified ? "successful" : "failed");
2194         
2195         EVP_PKEY_free(downloadedKey);
2196         EVP_PKEY_free(pubKey);
2197         EVP_PKEY_free(privKey);
2198         return verified;
2199 }
2200
2201 bool basicChecksumTest()
2202 {
2203         PhysicalEntity* bus1 = new PhysicalEntity("http://www.volvo.com/bus");
2204         bus1->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 5500));
2205         bus1->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
2206         bus1->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 11));
2207
2208         PhysicalEntity* bus2 = new PhysicalEntity("http://www.volvo.com/bus");
2209         bus2->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 5500));
2210         bus2->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 11));
2211         bus2->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
2212
2213         QString b1Check = bus1->generateChecksum();
2214         QString b2Check = bus2->generateChecksum();
2215         bus1->destroyCascade();
2216         bus2->destroyCascade();
2217         qDebug() << "Basic checksum test checksums:";
2218         qDebug() << "Item 1:" << b1Check;
2219         qDebug() << "Item 2:" << b2Check;
2220         return b1Check == b2Check;
2221 }
2222
2223 bool parsedChecksumTest()
2224 {
2225         PhysicalEntity* bus = new PhysicalEntity("http://www.volvo.com/bus");
2226
2227         bus->setWeight(new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 5500));
2228         bus->add(NS__SMARTAPI + "weight", new ValueObject(NS__UNIT + "Kilogram", NS__QUANTITY + "kilos", 1000));
2229
2230         bus->add(NS__SMARTAPI + "maximumAcceleration", new ValueObject(NS__UNIT + "MeterPerSecondSquared", 11));
2231
2232         QString serialized = Tools::toString(bus, SERIALIZATION__TURTLE);
2233         QString checksum = bus->generateChecksum();
2234
2235         printf("Object:\n%s\n", serialized.toUtf8().data());
2236         printf("Checksum: %s\n", checksum.toUtf8().data());
2237
2238         Obj* parsedObj = Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
2239         QString newChecksum = parsedObj->generateChecksum();
2240         printf("Checksum from parsed: %s\n", newChecksum.toUtf8().data());
2241         bus->destroyCascade();
2242         parsedObj->destroyCascade();
2243         return newChecksum == checksum;
2244 }
2245
2246 bool crossChecksumTest()
2247 {
2248         Velocity* v1 = new Velocity();
2249         v1->setLinearVelocityX(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(30)));
2250         v1->setLinearVelocityY(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(100)));
2251
2252         QString v1checksum = v1->generateChecksum();
2253
2254                 // velocity with flipped values
2255         Velocity* v2 = new Velocity();
2256         v2->setLinearVelocityX(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(100)));
2257         v2->setLinearVelocityY(new ValueObject(RESOURCE__LINEARVELOCITY, RESOURCE__KILOMETERPERHOUR, new Variant(30)));
2258
2259         QString v2checksum = v2->generateChecksum();
2260
2261         qDebug() << "Test 1, Checksum v1: " << v1checksum;
2262         qDebug() << "Test 1, Checksum v2: " << v2checksum;
2263         v1->destroyCascade();
2264         v2->destroyCascade();
2265
2266         Device* d1 = new Device();
2267         d1->addValueObject(new ValueObject(NS__SMARTAPI + "InsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(30)));
2268         d1->addValueObject(new ValueObject(NS__SMARTAPI + "OutsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(100)));
2269
2270         QString d1checksum = d1->generateChecksum();
2271
2272         // device with flipped values
2273         Device* d2 = new Device();
2274         d2->addValueObject(new ValueObject(NS__SMARTAPI + "InsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(100)));
2275         d2->addValueObject(new ValueObject(NS__SMARTAPI + "OutsideTemperature", RESOURCE__DEGREECELSIUS, new Variant(30)));
2276
2277         QString d2checksum = d2->generateChecksum();
2278         qDebug() << "Test 2, Checksum v1: " << d1checksum;
2279         qDebug() << "Test 2, Checksum v2: " << d2checksum;
2280         d1->destroyCascade();
2281         d2->destroyCascade();
2282
2283         return v1checksum != v2checksum && d1checksum != d2checksum;
2284 }
2285
2286 bool simpleHashTest()
2287 {
2288         QString r = "Simple hash input";
2289         QString responseHash = SmartAPICrypto::createEncodedMessageDigest(r);
2290         qDebug() << "Hash for the text: " << responseHash;
2291         return true;
2292 }
2293
2294 bool symmetricEncryptionTest()
2295 {
2296         QByteArray key = SmartAPICrypto::generateSymmetricKey();
2297         QString content = "Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2298
2299         QString encrypted = SmartAPICrypto::symmetricEncrypt((unsigned char*)key.data(), content);
2300         QString decrypted = SmartAPICrypto::symmetricDecrypt((unsigned char*)key.data(), encrypted);
2301         qDebug() << "Symmetric - decrypted" << decrypted;
2302         return decrypted == content;
2303 }
2304
2305 bool asymmetricEncryptionTest()
2306 {
2307         QString content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2308
2309         EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2310         EVP_PKEY* pubKey = getPemPublicKey("../../Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
2311         QByteArray symKeyHolder;
2312
2313         QString encrypted = SmartAPICrypto::asymmetricEncrypt(pubKey, content, &symKeyHolder);
2314         QString decrypted = SmartAPICrypto::asymmetricDecrypt(privKey, encrypted, &symKeyHolder);
2315         qDebug() << "Asymmetric - decrypted" << decrypted;
2316         EVP_PKEY_free(privKey);
2317         EVP_PKEY_free(pubKey);
2318         return decrypted == content;
2319 }
2320
2321 bool simpleSignatureTest()
2322 {
2323         QString content = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in lectus at sem commodo venenatis. Fusce in eros ex. In hac habitasse platea dictumst. Phasellus dignissim, augue vel aliquet pretium, nibh eros tristique est, dignissim aliquet elit justo vel mauris. Vestibulum a posuere nulla. Curabitur aliquam semper sagittis.";
2324         EVP_PKEY* privKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2325         qDebug() << "privKey =" << privKey;
2326
2327         QString signature = SmartAPICrypto::sign(privKey, content);
2328         qDebug() << "New signature" << signature;
2329         EVP_PKEY_free(privKey);
2330         return true;
2331 }
2332
2333 bool hashVerificationTest()
2334 {
2335         QString r = "Some digest input";
2336         QString digest = SmartAPICrypto::createEncodedMessageDigest(r);
2337         qDebug() << "Generated digest:" << digest;
2338         bool match = SmartAPICrypto::verifyEncodedMessageDigest(digest, r);
2339         qDebug() << "Digest match: " << match;
2340         return match;
2341 }
2342
2343 bool keyGenerationTest()
2344 {
2345         QString myId = "http://www.acme.com/services/abcd/1";
2346         QString publicKeyServer = "http://127.0.0.1:11371";
2347         SmartAPICrypto::createAndSaveKeyPair(myId, "/tmp/testkey_private.pem", publicKeyServer, "test", "test");
2348         return true;
2349 }
2350
2351 bool keyRevokationTest()
2352 {
2353         QString myId = "http://www.acme.com/services/abcd/1";
2354         QString publicKeyServer = "http://127.0.0.1:11371";
2355         return SmartAPICrypto::revokePublicKey(myId, publicKeyServer, "test", "test");
2356 }
2357
2358 bool keyUploadTest()
2359 {
2360         QString myId = "http://www.acme.com/services/abcd/2";
2361         QString publicKeyServer = "http://127.0.0.1:11371";
2362         QString pub, priv;
2363         Tools::createCryptoKeys(&priv, &pub);
2364         qDebug() << priv;
2365         qDebug() << pub;
2366         Tools::uploadPublicKey(pub, myId, publicKeyServer, "test", "test");
2367         Tools::revokePublicKey(myId, publicKeyServer, "test", "test");
2368         qDebug() << "Key uploaded and revoked";
2369         return true;
2370 }
2371
2372 bool keyEncryptionTest()
2373 {
2374         EVP_PKEY* pubKey = getPemPublicKey("../../Common/Java/SmartAPI/src/smartapi/tests/testkey_public.pem");
2375         EVP_PKEY* privKey = getPemPrivateKey("../../Common/Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2376
2377         QByteArray key = SmartAPICrypto::generateSymmetricKey();
2378         QString encodedKey = SmartAPICrypto::encryptAndEncodeKey(pubKey, key);
2379         QByteArray decodedKey = SmartAPICrypto::decryptAndDecodeKey(privKey, encodedKey);
2380         qDebug() << "original key:" << key.toBase64();
2381         qDebug() << "encrypted key:" << encodedKey;
2382         qDebug() << "decrypted key:" << decodedKey.toBase64();
2383         
2384         EVP_PKEY_free(privKey);
2385         EVP_PKEY_free(pubKey);
2386         return true;
2387 }
2388
2389 bool crossSystemDecryptionTest()
2390 {
2391         QString encrypted = "GUsjdd81ugIzil2isjteOQ==tPkIcebSOYdsS+o6fecuk4MSsA6P++HBv9/7MDuruGvCQvBAAAuMZb5mqyqg/oIjGwAavhi7RHFMG8OtDabbRywW8cWEmt6KKj96fAnozvzuvSbduguOtIiuzgwPVmxURPzHhoKM08bvoQDzhXsfA5YY5eBNDq3SdUHSQIl7rWeyKATjUXOZhlWNwjwkcztF4UCj+g2YcoFRtlaxKFxON2LsGNcNrQght/SBWfX00qys9uXuii9GgMnXjMuP/BlRMC3AZms3BBVAgJD9MvdkBAdU9jN6hpdC0WkXc1IPIumdk5W8jg7mIg9HCzs/g4phGQG5CbHDuSLcns95O5emrNls9K9n0olI7SWfeFwNRimuOUqOk5fO26I7/ELu1jnvVppFzt4MBr13E67CR7PvnQ==";
2392         QString key = "adUiExOZ/L05Hds1r4W2vg==";
2393         QByteArray decodedKey = SmartAPICrypto::decodeBase64EncodedKey(key);
2394
2395         QString decrypted = SmartAPICrypto::symmetricDecrypt((unsigned char*)decodedKey.data(), encrypted);
2396         printf("%s\n", decrypted.toUtf8().data());
2397         return decrypted.startsWith("The") && decrypted.endsWith(". ");
2398 }
2399
2400 bool solarPanelClientTest()
2401 {
2402         QNetworkAccessManager *networkManager = new QNetworkAccessManager();
2403         OAuthAgent* oauthAgent = new OAuthAgent(networkManager);
2404         EVP_PKEY* myPrivateKey = getPemPrivateKey("../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
2405         if (!myPrivateKey) {
2406                 qDebug() << "Cannot load private key. Check the path.";
2407                 return false;
2408         }
2409
2410         QString myIdentity = "http:///www.client.com/seas/Cclient";
2411         QString clientSecret = "asdf";
2412         //QString panelGatewayAddress = "http://development.asema.com:2888/solarpanelgateway/";
2413         //QString panelGatewayAddress = "http://127.0.0.1:2888/solarpanelgateway/";
2414         //QString securityBrokerAddress = "http://development.asema.com:11372/oauth2/";
2415         //QString securityBrokerAddress = "http://127.0.0.1:2872/oauth2/";
2416         QString panelGatewayAddress = "http://127.0.0.1:8080/solarpanelgateway/";
2417         QString securityBrokerAddress = "http://127.0.0.1:11372/oauth2/";
2418
2419         QString dataEndpoint = panelGatewayAddress + "seas/v1.0e1.0/access/";
2420         QString authorizeEndpoint = panelGatewayAddress + "authorize";
2421         QString tokenEndpoint = securityBrokerAddress + "token";
2422         QString clientId = "SolarPanelTestApp";
2423         QString authorizationCode;
2424         QString authToken;
2425         QStringList panelIds;
2426         panelIds << "http://seas.asema.com/dataservice/solar/Paris/panels/1";
2427         panelIds << "http://seas.asema.com/dataservice/solar/Paris/panels/2";
2428
2429         // the following is basically the Java implementation of SolarPanelClient.requestDataFromGateway() translated to C++
2430         QMap<QString, QList<QMap<QDateTime, double> > > results;
2431         QListIterator<QString> pi(panelIds);
2432         while (pi.hasNext()) {
2433                 QString panelId = pi.next();
2434                 Activity* requestActivity = NULL;
2435                 // create request activity
2436                 Activity* requestActivityTemplate = new Activity();
2437                 Input* i = new Input();
2438                 requestActivityTemplate->addInput(i);
2439                 i->setCategory(RESOURCE__SOLARENERGYPRODUCTION);
2440                 i->setSystemOfInterestWithSameAs(panelId);
2441                 ValueObject* vo = new ValueObject();
2442                 vo->setQuantity(RESOURCE__ENERGYANDWORK);
2443                 vo->setUnit(RESOURCE__MEGAWATTHOUR);
2444                 i->addOutputValue(vo);
2445
2446                 // create start and end timestamps
2447                 // start = 1 day ago
2448                 // end = now
2449                 QDateTime now = QDateTime::currentDateTime();
2450                 QDateTime start = now.addDays(-1);
2451                 i->setTemporalContext(start, now);
2452
2453                 bool activityPaid = false;
2454                 while (true) {
2455                         // request data
2456                         Request* r = RequestFactory::create(myIdentity);
2457                         r->setMethod(QUrl(RESOURCE__READ)); // FIXME is this right?
2458
2459                         if (requestActivity != NULL)
2460                                 r->addActivity(new Activity(requestActivity));
2461                         else
2462                                 r->addActivity(new Activity(requestActivityTemplate));
2463
2464                         HttpMessage* httpMessage = Tools::serializeRequest(r);
2465                         r->destroyCascade();
2466
2467                         QNetworkReply* reply = httpMessage->post(networkManager, dataEndpoint, "Request", clientId.toLocal8Bit(), QMap<QString, QString>(), CONTENT_TYPE__TURTLE, CONTENT_TYPE__TURTLE, authToken);
2468                         QEventLoop loop;
2469                         QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
2470                         loop.exec();
2471
2472                         QByteArray responseString = reply->readAll();
2473                         int httpStatus = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
2474                         if (httpStatus != 200) {
2475                                 // not authenticated
2476                                 qDebug() << "not authenticated. authToken is" << authToken;
2477                                 if (authToken.isEmpty()) {
2478                                         authorizationCode = oauthAgent->oauth2AuthorizeApplication(authorizeEndpoint, clientId, "api");
2479                                         authToken = oauthAgent->oauth2AuthenticateUser(tokenEndpoint, authorizationCode, clientId, clientSecret, "");
2480                                         qDebug() << "Got authorization to access the server with token " << authToken;
2481                                         continue;
2482                                 } else {
2483                                         qDebug() << "Already authenticated but server still requests authentication. Aborting.";
2484                                         return false;
2485                                 }
2486                         }
2487                         QByteArray contentType = reply->header(QNetworkRequest::ContentTypeHeader).toByteArray();
2488                         reply->deleteLater();
2489
2490                         //qDebug() << "Response from panel gateway:----- ";
2491                         //printf("%s\n", responseString.constData());
2492                         //qDebug() << "------ContentType------";
2493                         //qDebug() << contentType;
2494
2495                         Response* response = Tools::parseResponse(responseString, contentType);
2496
2497                         if (response == NULL) {
2498                                 qDebug() << "Could not parse the data.";
2499                                 //continue;
2500                                 return false;
2501                         }
2502
2503                         if (response->hasActivity()) {
2504                                 Activity* respActivity = response->getActivities().first();
2505                                 if (respActivity->hasOutput()) {
2506                                         // Output received OK
2507                                         qDebug() << "Got data for panel OK!";
2508                                 } else if (respActivity->hasOffering()) {
2509                                         // Output not received, a payment is requested
2510                                         if (!activityPaid) {
2511                                                 requestActivity = new Activity(respActivity);
2512
2513                                                 Offering* offering = requestActivity->getOfferings().first();
2514                                                 QListIterator<PriceSpecification*> psi(offering->getPriceSpecification().toQList());
2515                                                 while (psi.hasNext()) {
2516                                                         PriceSpecification* ps = psi.next();
2517                                                         qDebug() << "Received an offer to pay for the data request, price is" << ps->getCurrencyValue() << ps->getCurrency();
2518                                                         qDebug() << "Accepting it.";
2519                                                 }
2520
2521                                                 /*
2522                         printf("~~~ RESP ACTIVITY ~~~\n\n%s\n\n", Tools::toString(respActivity, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2523                         printf("~~~ REQUEST ACTIVITY ~~~\n\n%s\n\n", Tools::toString(requestActivity, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2524                         return;
2525                         */
2526
2527                                                 offering->sign(myPrivateKey);
2528                                                 activityPaid = true;
2529                                                 continue;
2530                                         } else {
2531                                                 qDebug() << "Already signed the offering but server still requests payment. Aborting.";
2532                                                 return false;
2533                                         }
2534                                 }
2535                         } else {
2536                                 qDebug() << "response has no activity!";
2537                                 return false;
2538                         }
2539
2540                         if (response == NULL) {
2541                                 qDebug() << "Response is null. Exiting.";
2542                                 return false;
2543                         }
2544
2545                         qDebug() << "--- Got response from panel gateway";
2546                         qDebug() << Tools::toString(response, SERIALIZATION__TURTLE);
2547
2548                         Activity* responseActivity = response->getActivities().first();
2549                         if (responseActivity->hasOutput()) {
2550                                 QListIterator<Output*> oi(responseActivity->getOutputs().toQList());
2551                                 while (oi.hasNext()) {
2552                                         Output* out = oi.next();
2553                                         if (out->isEncrypted()) {
2554                                                 qDebug() << "encrypted content:";
2555                                                 qDebug() << out->getStringRepresentation();
2556
2557                                                 bool result = true;
2558                                                 if (out->getEncryptionKeyType() == RESOURCE__PUBLICKEY) {
2559                                                         result = out->decrypt(myPrivateKey);
2560                                                 } else if (out->getEncryptionKeyType() == RESOURCE__NOTARIZEDSESSIONKEY) {
2561                                                         QString signature = SmartAPICrypto::sign(myPrivateKey, out->getHashCode());
2562                                                         qDebug() << "This is a notarized message, key at" << out->getNotary();
2563                                                         TransactionAgent agent;
2564                                                         QString keyString = agent.fetchKeyFromNotary(myIdentity,
2565                                                                         out->getIdentifierUri(),
2566                                                                         out->getHashCode(),
2567                                                                         signature,
2568                                                                         out->getNotary(),
2569                                                                         myPrivateKey);
2570                                                         qDebug() << "The keystring is" << keyString;
2571                                                         QByteArray secretKey = SmartAPICrypto::decryptAndDecodeKey(myPrivateKey, keyString);
2572                                                         result = out->decrypt(secretKey);
2573                                                         qDebug() << "decrypted output------------------";
2574                                                         qDebug() << Tools::toString(out, SERIALIZATION__TURTLE);
2575                                                 }
2576
2577                                                 if (!result) {
2578                                                         qDebug() << "decryption failed!";
2579                                                         return false;
2580                                                 } else {
2581                                                         qDebug() << "decrypted successfully!!!";
2582                                                 }
2583                                         }
2584
2585                                         QList<QMap<QDateTime, double> > timeSeriesList;
2586
2587                                         // Fill timeseries from the output here
2588                                         if (out->hasTimeSerie()) {
2589                                                 qDebug() << "Filling the timeseries data";
2590                                                 TimeSeries* ts = out->getTimeSeries().first();
2591                                                 QListIterator<GraphItem*> tsi(ts->getList().toQList());
2592                                                 while (tsi.hasNext()) {
2593                                                         Evaluation* tse = dynamic_cast<Evaluation*>(tsi.next());
2594                                                         qDebug() << "Data for" << tse->getInstant();
2595                                                 }
2596                                         }
2597
2598                                         results.insert(panelId, timeSeriesList);
2599                                 }
2600
2601                                 // request completed, so exit the forever loop
2602                                 break;
2603                         }
2604                         delete response;
2605                 }
2606                 delete requestActivityTemplate;
2607         }
2608
2609         qDebug() << "test finished!";
2610         return true;
2611 }
2612
2613 bool currencyConversionTest()
2614 {
2615         QNetworkAccessManager* networkManager = new QNetworkAccessManager();
2616         UnitConverter u(networkManager);
2617
2618         QEventLoop waitLoop;
2619         QObject::connect(&u, SIGNAL(ready()), &waitLoop, SLOT(quit()));
2620         u.load();
2621         waitLoop.exec( QEventLoop::ExcludeUserInputEvents );
2622
2623
2624         ValueObject* testA = new ValueObject(RESOURCE__POWER, NS__UNIT + "Watt", 2.2);
2625         ValueObject* testB = new ValueObject(RESOURCE__CURRENCY, RESOURCE__EURO, 2.2);
2626         testB->setSecondaryQuantity(RESOURCE__ENERGYANDWORK);
2627         testB->setSecondaryUnit(RESOURCE__KILOWATTHOUR);
2628
2629         ValueObject* testC = new ValueObject(RESOURCE__CURRENCY, RESOURCE__EURO, 10);
2630         ValueObject* testD = new ValueObject(RESOURCE__TEMPERATURE, NS__UNIT + "Kelvin", 283.15);
2631         ValueObject* testE = new ValueObject(RESOURCE__TEMPERATURE, NS__UNIT + "DegreeCelsius", 10);
2632
2633         testA->turtlePrint();
2634         u.convert(testA, NS__UNIT + "Kilowatt");
2635         testA->turtlePrint();
2636
2637         testB->turtlePrint();
2638         u.convert(testB, RESOURCE__POUNDSTERLING, RESOURCE__MEGAWATTHOUR);
2639         testB->turtlePrint();
2640
2641         testC->turtlePrint();
2642         u.convert(testC, RESOURCE__POUNDSTERLING);
2643         testC->turtlePrint();
2644
2645         testD->turtlePrint();
2646         u.convert(testD, NS__UNIT + "DegreeFahrenheit");
2647         testD->turtlePrint();
2648
2649         testE->turtlePrint();
2650         u.convert(testE, NS__UNIT + "DegreeFahrenheit");
2651         testE->turtlePrint();
2652
2653         testA->destroyCascade();
2654         testB->destroyCascade();
2655         testC->destroyCascade();
2656         testD->destroyCascade();
2657         testE->destroyCascade();
2658
2659         return true;
2660 }
2661
2662
2663 bool registrationTest()
2664 {
2665         RegisterDeregisterTest* test = new RegisterDeregisterTest();
2666         test->doTest();
2667 }
2668
2669 bool registrationSearchTest()
2670 {
2671         RegisterSearchTest* test = new RegisterSearchTest();
2672         test->doTest();
2673 }
2674
2675 bool multiParseTest()
2676 {
2677         Request* request = RequestFactory::create("http://test.iot.com/test");
2678         request->setMethod(NS__SMARTAPI + "Read");
2679
2680         Activity* activity = new Activity();
2681         Input* input = new Input();
2682
2683         SystemOfInterest* sys_of_interest = new SystemOfInterest();
2684         sys_of_interest->setType(NS__SMARTAPI + "Test");
2685         input->setSystemOfInterest(sys_of_interest);
2686
2687         Coordinates* coordinates = new Coordinates(40.000, 2.000);
2688         input->add("search_coordinates", new Variant(coordinates));
2689
2690         activity->addInput(input);
2691         request->addActivity(activity);
2692
2693         QString payload = Tools::toString(request, SERIALIZATION__TURTLE);
2694         Request* req1 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2695         Request* req2 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2696         Request* req3 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2697         Request* req4 = (Request*)Tools::fromStringAsObj(payload, SERIALIZATION__TURTLE);
2698
2699         req1->destroyCascade();
2700         request->destroyCascade();
2701         req4->destroyCascade();
2702         req2->destroyCascade();
2703         req3->destroyCascade();
2704
2705         return true;
2706 }
2707
2708
2709 //bool sharingTest()
2710 //{
2711 //    // generate key pairs
2712 //    EVP_PKEY* iotc1PrivateKey;
2713 //    EVP_PKEY* iotc1PublicKey;
2714 //    EVP_PKEY* iotc2PrivateKey;
2715 //    EVP_PKEY* iotc2PublicKey;
2716 //    SmartAPICrypto::generateKeyPair(&iotc1PrivateKey, &iotc1PublicKey);
2717 //    SmartAPICrypto::generateKeyPair(&iotc2PrivateKey, &iotc2PublicKey);
2718
2719 //    QString iotc1Identity = "http://acme.com/iotc-1/C756fdg76dgfh4376dshg";
2720
2721 //    // (1) IoTC 1 registers with RegistrationAgent
2722 //    QString powerIdentifier = "/Cpower";
2723 //    QString volumeIdentifier = "/Cvolume";
2724 //    QString controlOfferingIdentifier ="/Ccontroloffering";
2725 //    QString dataOfferingIdentifier = "/dataCoffering";
2726
2727 //    // create boiler
2728 //    Device* boiler = new Device(iotc1Identity);
2729 //    boiler->addType(RESOURCE__WATERBOILER);
2730
2731 //    // info about energy consumption (power capacity)
2732 //    Capacity* power = new Capacity(iotc1Identity + powerIdentifier);
2733 //    power->setSystemOfInterestWithType(RESOURCE__RESISTOR);
2734 //    power->setQuantity(RESOURCE__POWER);
2735 //    power->setUnit(RESOURCE__KILOWATT);
2736 //    power->setMaximum(new Variant(6));
2737 //    power->setStep(new Variant(3));
2738 //    power->setValue(new Variant(6));
2739 //    boiler->addCapacity(power);
2740
2741 //    // info about water volume (volume capacity)
2742 //    Capacity* volume = new Capacity(iotc1Identity + volumeIdentifier);
2743 //    volume->setSystemOfInterestWithType(RESOURCE__WATERTANK);
2744 //    volume->setQuantity(RESOURCE__VOLUME);
2745 //    volume->setUnit(RESOURCE__LITER);
2746 //    volume->setMaximum(new Variant(500));
2747 //    volume->setValue(new Variant(500));
2748 //    boiler->addCapacity(volume);
2749
2750 //    // price for controlling on/off of this device
2751 //    Offering* controlOffering = new Offering(iotc1Identity + controlOfferingIdentifier);
2752 //    boiler->addOffering(controlOffering);
2753 //    PriceSpecification* controlPriceSpecification = new UnitPriceSpecification();
2754 //    controlPriceSpecification->setGrName("Price to control this boiler");
2755 //    controlPriceSpecification->setGrDescription("The amount in Euro to be paid for being able to control the two 3 kW resistors of this boiler for one hour.");
2756 //    controlPriceSpecification->setCurrency("EUR");
2757 //    controlPriceSpecification->setCurrencyValue(1.5);
2758 //    controlOffering->addPriceSpecification(controlPriceSpecification);
2759 //    // offer item is a one hour subscription for controlling
2760 //    SomeItems* controlItems = new SomeItems(RESOURCE__SERVICESUBSCRIPTION, "Service subscription", "Right to control this device for one hour.", NULL);
2761 //    controlItems->setDuration(0, 0, 0, 1, 0, 0);
2762 //    controlItems->setMethod(RESOURCE__WRITE);
2763 //    controlOffering->addIncludes(controlItems);
2764
2765 //    // price for subscribing to receive data values of this device
2766 //    Offering* readOffering = new Offering(iotc1Identity + dataOfferingIdentifier);
2767 //    boiler->addOffering(readOffering);
2768 //    PriceSpecification* readPriceSpecification = new UnitPriceSpecification();
2769 //    readPriceSpecification->setGrName("Price to subscribe to receive real-time values");
2770 //    readPriceSpecification->setGrDescription("The amount in Euro to be paid for being able to receive real-time values for power and volume of this boiler for one day.");
2771 //    readPriceSpecification->setCurrency("EUR");
2772 //    readPriceSpecification->setCurrencyValue(0.05);
2773 //    readOffering->addPriceSpecification(readPriceSpecification);
2774 //    // offer item is a one day subscription for reading
2775 //    SomeItems* readItems = new SomeItems(RESOURCE__SERVICESUBSCRIPTION, "Service subscription", "Right to receive data values of this device for one day", NULL);
2776 //    readItems->setDuration(0, 0, 1, 0, 0, 0);
2777 //    readItems->setMethod(RESOURCE__SUBSCRIBE);
2778 //    readOffering->addIncludes(readItems);
2779
2780 //    // activity for subscribing to follow values of this entity
2781 //    Activity* subsActivity = new Activity();
2782 //    subsActivity->setMethod(RESOURCE__SUBSCRIBE);
2783 //    boiler->addCapability(subsActivity);
2784
2785 //    // input for defining requested capacities
2786 //    Input* subsInput = new Input();
2787 //    subsActivity->addInput(subsInput);
2788 //    subsInput->addRequiredPropertyDescription(1, RESOURCE__SYSTEMOFINTEREST, PROPERTY__SYSTEMOFINTEREST);
2789 //    SystemOfInterest* subsSoi = new SystemOfInterest();
2790 //    subsInput->setSystemOfInterest(subsSoi);
2791 //    QStringList subsSoiDataRanges;
2792 //    subsSoiDataRanges << iotc1Identity + powerIdentifier << iotc1Identity + volumeIdentifier;
2793 //    subsSoi->addRequiredPropertyDescription(1, 2, subsSoiDataRanges, PROPERTY__SAMEAS);
2794 //    subsInput->addOptionalPropertyDescription(1, RESOURCE__RDFS_RESOURCE, PROPERTY__PUBLICKEYSERVER);
2795 //    InterfaceAddress* subsInInterface = new InterfaceAddress();
2796 //    subsInput->addInterface(subsInInterface);
2797 //    subsInput->addRequiredPropertyDescription(1, RESOURCE__INTERFACEADDRESS, PROPERTY__INTERFACE);
2798
2799 //    // output to define output and its mqtt interface
2800 //    Output* subsOutput = new Output(Output::TYPE_REFERENCE);
2801 //    subsActivity->addOutput(subsOutput);
2802 //    subsOutput->addRequiredPropertyDescription(1, RESOURCE__INTERFACEADDRESS, PROPERTY__INTERFACE);
2803 //    InterfaceAddress* subsOutInterface = new InterfaceAddress();
2804 //    subsOutInterface->addContentType(CONTENT_TYPE__TURTLE);
2805 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__STRING, PROPERTY__HOST);
2806 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__INT, PROPERTY__PORT);
2807 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__STRING, PROPERTY__SCHEME);
2808 //    subsOutInterface->addRequiredPropertyDescription(1, DATATYPE__STRING, PROPERTY__TOPIC);
2809 //    subsOutput->addInterface(subsOutInterface);
2810 //    subsOutput->addRequiredPropertyDescription(1, RESOURCE__ENTITY, PROPERTY__ENTITY);
2811 //    Entity* subsOutEntity = new Entity();
2812 //    subsOutEntity->addRequiredPropertyDescription(1, 2, RESOURCE__CAPACITY, PROPERTY__CAPACITY);
2813
2814 //    // interface for making subscription
2815 //    InterfaceAddress* iData = new InterfaceAddress();
2816 //    subsActivity->addInterface(iData);
2817 //    iData->addContentType(CONTENT_TYPE__TURTLE);
2818 //    iData->setHost("acme.com");
2819 //    iData->setPath("/data");
2820 //    iData->setPort(80);
2821 //    iData->setScheme("http");
2822
2823 //    // interface for mqtt notifications
2824 //    InterfaceAddress* iMqtt = new InterfaceAddress();
2825 //    subsActivity->addInterface(iMqtt);
2826 //    iMqtt->addContentType(CONTENT_TYPE__TURTLE);
2827 //    iMqtt->setHost("seas.asema.com");
2828 //    iMqtt->setPort(1883);
2829 //    iMqtt->setScheme("mqtt");
2830 //    QStringList iMqttTopic;
2831 //    iMqttTopic << iotc1Identity;
2832 //    iMqttTopic << RESOURCE__DEVICE;
2833 //    iMqtt->setTopic(iMqttTopic);
2834
2835 //    // interface for websocket notifications
2836 //    InterfaceAddress* iWS = new InterfaceAddress();
2837 //    subsActivity->addInterface(iWS);
2838 //    iWS->addContentType(CONTENT_TYPE__TURTLE);
2839 //    iWS->setHost("seas.asema.com");
2840 //    iWS->setPort(80);
2841 //    iWS->setScheme("ws");
2842
2843 //    // activity for controlling this device
2844 //    Activity* writeActivity = new Activity();
2845 //    writeActivity->setMethod(RESOURCE__WRITE);
2846 //    boiler->addCapability(writeActivity);
2847
2848 //    // input for defining target value(s)
2849 //    Input* writeInput = new Input();
2850 //    writeActivity->addInput(writeInput);
2851 //    writeInput->addRequiredPropertyDescription(1, RESOURCE__SYSTEMOFINTEREST, PROPERTY__SYSTEMOFINTEREST);
2852 //    SystemOfInterest* writeSoi = new SystemOfInterest();
2853 //    writeInput->setSystemOfInterest(writeSoi);
2854 //    QStringList writeSoiDataRanges;
2855 //    writeSoiDataRanges << iotc1Identity + powerIdentifier << iotc1Identity + volumeIdentifier;
2856 //    writeSoi->addRequiredPropertyDescription(1, writeSoiDataRanges, PROPERTY__SAMEAS);
2857 //    writeInput->addRequiredPropertyDescription(1, RESOURCE__LITERAL, PROPERTY__RDF_VALUE);
2858
2859 //    // output containing current values
2860 //    Output* writeOutput = new Output();
2861 //    writeActivity->addOutput(writeOutput);
2862 //    writeOutput->addRequiredPropertyDescription(1, RESOURCE__ENTITY, PROPERTY__ENTITY);
2863
2864 //    // interface for control commands (same as making subscriptions)
2865 //    writeActivity->addInterface(iData);
2866
2867 //    // availability of the boiler (7 days from now)
2868 //    Availability* availability1 = new Availability();
2869 //    QDateTime now = QDateTime::currentDateTime();
2870 //    availability1->setTemporalContext(now, now.addDays(7));
2871
2872 //    // debug print registration description
2873 //    qDebug() << "(1) Device registration:";
2874 //    printf("%s\n", Tools::toString(boiler, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2875
2876 //    // registrate boiler description
2877 //    RegistrationAgent* registrationAgent = new RegistrationAgent(iotc1Identity + "/registrator"); // FIXME this /registrator suffix is needed because of a serialization bug that Hannu is working on
2878 //    //registrationAgent->addEntity(boiler);
2879 //    QEventLoop loop;
2880 //    QObject::connect(registrationAgent, SIGNAL(registrationSucceeded(int)), &loop, SLOT(quit()));
2881 //    if (!registrationAgent->makeRegistration(boiler)) {
2882 //        qCritical() << "RegistrationAgent::makeRegistration failed!";
2883 //        return false;
2884 //    }
2885 //    qDebug() << "waiting for registrationSucceeded signal...";
2886 //    loop.exec();
2887 //    qDebug() << "Registration made.";
2888
2889 //    // (2) IoTC 1 shares availability with SharingAgent
2890 //    qDebug() << "(2) Share availability";
2891 //    Availability* availability2 = new Availability();
2892 //    now = QDateTime::currentDateTime();
2893 //    availability2->addAvailability(now, now.addDays(14));
2894
2895 //    qDebug() << "Shared availability:";
2896 //    printf("%s\n", Tools::toString(availability2, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2897
2898 //    // share with defined availability
2899 //    SharingAgent* sharingAgent = new SharingAgent(iotc1Identity + "/registrator");
2900 //    if (sharingAgent->share(iotc1Identity, availability2)) {
2901 //        qDebug() << "Availability successfully added.";
2902 //    } else {
2903 //        qCritical() << "Failed to add availability!";
2904 //        return false;
2905 //    }
2906
2907 //    // (3) IoTC2 searches for available devices with SharingAgent
2908 //    // search for available devices with power capacity
2909 //    qDebug() << "(3) Search for available devices with power capacity";
2910 //    Entity* entity = new Device();
2911 //    Capacity* capacity = new Capacity();
2912 //    capacity->setQuantity(RESOURCE__POWER);
2913 //    entity->addCapacity(capacity);
2914
2915 //    // ...that are available from now on for at least 1 day...
2916 //    Availability* av = new Availability();
2917 //    QDateTime currentDateTime = QDateTime::currentDateTime();
2918 //    av->setTemporalContext(currentDateTime, currentDateTime.addDays(1));
2919
2920 //    // ...with maximum price of 0.05 euros per day
2921 //    Offering* offer = new Offering();
2922 //    PriceSpecification* ps = new UnitPriceSpecification();
2923 //    ps->setCurrency("EUR");
2924 //    ps->setCurrencyValue(0.05);
2925 //    offer->addPriceSpecification(ps);
2926 //    SomeItems* si = new SomeItems(RESOURCE__SERVICESUBSCRIPTION, QString(), QString(), QString());
2927 //    si->setDuration(0, 0, 1, 0, 0, 0);
2928 //    offer->addIncludes(si);
2929
2930 //    // debug print offering and availability search parameter objects
2931 //    printf("Search availability parameter:\n%s\n", Tools::toString(av, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2932 //    printf("Search offer parameter:\n%s\n", Tools::toString(offer, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2933
2934 //    SharingAgent* searchAgent = new SharingAgent("http://acme.com/test/searcher");
2935 //    bool foundBoiler = false;
2936 //    QList<Offering*> offerings;
2937 //    offerings << offer;
2938 //    QList<Entity*> found = searchAgent->search(entity, av, offerings);
2939 //    qDebug() << "found length is" << found.length();
2940 //    Device* iotc1 = NULL;
2941 //    QListIterator<Entity*> foundIter(found);
2942 //    while (foundIter.hasNext()) {
2943 //        Entity* e = foundIter.next();
2944 //        qDebug() << "next entity:" << e->getIdentifierUri();
2945 //        if (iotc1Identity == e->getIdentifierUri()) {
2946 //            foundBoiler = true;
2947 //            iotc1 = dynamic_cast<Device*>(e);
2948 //        }
2949 //    }
2950
2951 //    if (!foundBoiler) {
2952 //        qCritical() << "Could not find boiler using sharing agent!";
2953 //        return false;
2954 //    }
2955
2956 //    qDebug() << "boiler found:" << iotc1;
2957 //    return true;
2958 //}
2959
2960 bool identifierManagementTest()
2961 {
2962     qDebug() << "Running identifierManagementTest...";
2963     QString domain = "asema.com";
2964     QString systemId = "iotc/123";
2965     QString objId = "/obj%567&/>qwerty/";
2966
2967     Entity* e = new Entity(Tools::createIdentifierUri(domain, systemId, objId));
2968     qDebug() << "identifier creation successful";
2969     printf("%s\n", Tools::toString(e, SERIALIZATION__TURTLE).toLocal8Bit().constData());
2970     QString domain2 = e->getDomain();
2971     QString systemId2 = e->getSystemIdentifier();
2972     QString objId2 = e->getObjectIdentifier();
2973     QString secondObjectId = e->getObjectIdentifier(2);
2974     qDebug() << "domain:" << domain2;
2975     qDebug() << "systemId:" << systemId2;
2976     qDebug() << "objectId:" << objId2;
2977     qDebug() << "secondObjectId:" << secondObjectId;
2978     qDebug() << "identifier partition successful";
2979
2980     if (domain == domain2) {
2981         qDebug() << "domain correct";
2982     } else {
2983         qDebug() << "domain match FAILED!";
2984         return false;
2985     }
2986
2987     if (systemId == systemId2) {
2988         qDebug() << "systemId correct";
2989     } else {
2990         qDebug() << "systemId match FAILED!";
2991         return false;
2992     }
2993
2994     if (objId == objId2) {
2995         qDebug() << "objId correct";
2996     } else {
2997         qDebug() << "objId match FAILED!";
2998         return false;
2999     }
3000
3001     if (secondObjectId.isEmpty()) {
3002         qDebug() << "secondObjectId correct";
3003     } else {
3004         qDebug() << "secondObjectId match FAILED!";
3005         return false;
3006     }
3007
3008     e->destroyCascade();
3009     return true;
3010 }
3011
3012 bool priceSpecificationSerializeParseTest()
3013 {
3014         DistanceDependentPriceSpecification* ddps = new DistanceDependentPriceSpecification();
3015
3016         Coordinates* c = new Coordinates(20.1, 21.0);
3017     ddps->setCoordinates(c);
3018
3019         QString serialized = Tools::toString(ddps, SERIALIZATION__TURTLE);
3020         qDebug() << "Serialized:";
3021         printf("%s\n", serialized.toLatin1().data());
3022         ddps->destroyCascade();
3023
3024         qDebug() << "-------------------";
3025     DistanceDependentPriceSpecification* parsedEntity = (DistanceDependentPriceSpecification*)Tools::fromStringAsObj(serialized);
3026
3027         qDebug() << "\nRe-serializing...";
3028     QString reserializedPayload = Tools::toString(parsedEntity, SERIALIZATION__TURTLE);
3029         printf("%s\n", reserializedPayload.toLatin1().data());
3030
3031     parsedEntity->destroyCascade();
3032
3033     return true;
3034 }
3035
3036 bool priceSpecificationCopyTest()
3037 {
3038     Offering* o = new Offering("http://offering.com");
3039     PropertyDependentPriceSpecification* ps = new PropertyDependentPriceSpecification();
3040     ps->setUnit(RESOURCE__EURO);
3041     ps->setReferenceObject("http://someobject.com");
3042     ps->setProperty("http://proper.ty");
3043     Condition* c1 = new Condition();
3044     c1->addLesser(new Variant(10));
3045     c1->addAction(new Variant(5));
3046     ps->addCondition(c1);
3047     Condition* c2 = new Condition();
3048     c2->addGreaterOrEqual(new Variant(10));
3049     c2->addAction(new Variant(7));
3050     ps->addCondition(c2);
3051     o->addPriceSpecification(ps);
3052
3053     qDebug() << "original:";
3054     o->turtlePrint();
3055
3056     Offering* copy = new Offering(o);
3057     qDebug() << "copied:";
3058     copy->turtlePrint();
3059
3060 //    qDebug() << "orig unit" << o->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0);
3061 //    qDebug() << "copy unit" << copy->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0);
3062
3063 //    qDebug() << "orig unit" << ((Obj*)o->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0);
3064 //    qDebug() << "copy unit" << ((Obj*)copy->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0);
3065
3066     // test that local class pointers differ
3067     if (o->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0) == copy->getPriceSpecification().at(0)->getAll(PROPERTY__UNIT)->at(0)) {
3068         qDebug() << "Orignal and copied unit (variants) has same pointer while copy should be copied!";
3069         return false;
3070     }
3071
3072     // test that pointers in property map differ
3073     if (((Obj*)o->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0) == ((Obj*)copy->getAll(PROPERTY__HASPRICESPECIFICATION)->at(0))->getAll(PROPERTY__UNIT)->at(0)) {
3074         qDebug() << "Orignal and copied unit (variants) has same pointer while copy should be copied!";
3075         return false;
3076     }
3077
3078     o->destroyCascade();
3079     qDebug() << "copied after destroying original:";
3080     copy->turtlePrint();
3081
3082     if (copy->hasPriceSpecification() && ((PropertyDependentPriceSpecification*)copy->getPriceSpecification().at(0))->getConditions().length() == 2) {
3083         return true;
3084     } else {
3085         if (!copy->hasPriceSpecification()) {
3086             qDebug() << "copy->hasPriceSpecification() returned false!";
3087             return false;
3088         } else {
3089             qDebug() << "copied condition list size should be 2 but it is" << ((PropertyDependentPriceSpecification*)copy->getPriceSpecification().at(0))->getConditions().length();
3090         }
3091         return false;
3092     }
3093 }
3094
3095
3096 bool serializeParseSignedResponseTest()
3097 {
3098         EVP_PKEY* privKey = getPemPrivateKey("../../../Java/SmartAPI/src/smartapi/tests/testkey_private.pem");
3099         Response* r = new Response();
3100         Activity* a = new Activity("http://acme.com/activity");
3101         Input* i = new Input("http://acme.com/input");
3102         i->setName("My input");
3103         r->addActivity(a);
3104         a->addInput(i);
3105         r->sign(privKey);
3106
3107         // serialize parse
3108         HttpMessage* msg = Tools::serializeResponse(r, SERIALIZATION__TURTLE);
3109         Response* resp = Tools::parseResponse(msg->getAsByteArray(), msg->getContentType());
3110         resp->turtlePrint();
3111
3112         qDebug() << "resp->has(PROPERTY__ACTIVITY)" << resp->has(PROPERTY__ACTIVITY);
3113         qDebug() << "resp->hasActivity()" << resp->hasActivity();
3114
3115         if (!resp->hasActivity()) {
3116                 return false;
3117         }
3118
3119         r->destroyCascade();
3120         resp->destroyCascade();
3121         delete msg;
3122         return true;
3123 }
3124
3125 // FIXME this leaks memory!
3126 bool standardRWTest()
3127 {
3128     qDebug() << "Running standard RW test against SimpleRW servlet...";
3129
3130     SearchAgent* agent = new SearchAgent("http://unknown.seas.partner");
3131     /*
3132     StandardRequestAgent* srAgent = new StandardRequestAgent("http://unknown.seas.partner");
3133     //agent->setDebugMode(true);
3134     //srAgent->setDebugMode(true);
3135     QStringList keywords, types;
3136     keywords << "SimpleRW";
3137     types << RESOURCE__DEVICE;
3138
3139     QList<Entity*> entities = agent->searchByNameAndTypeSync(500, keywords, types);
3140     if (entities.isEmpty()) {
3141         qDebug() << "Standard RW test failed. No entities found on server.";
3142         return false;
3143     }
3144
3145     QListIterator<Entity*> ei(entities);
3146     while (ei.hasNext()) {
3147         Entity* e = ei.next();
3148
3149         ValueObject* brightness = e->getValueObject(NS__SMARTAPI + "Brightness");
3150         int brightnessValue = 0;
3151         bool powerValue = true;
3152
3153         // fetch brightness value
3154         QList<ValueObject*> b;
3155         b << brightness;
3156         Entity* updated = srAgent->getValueObject(e, b);
3157         brightnessValue = updated->getValueObject(NS__SMARTAPI + "Brightness")->getValueAsInt();
3158         qDebug() << "Read:" << brightnessValue;
3159
3160         // set new brightness value
3161         if (brightnessValue > 50) {
3162             brightnessValue = 30;
3163         } else {
3164             brightnessValue = 80;
3165         }
3166
3167         // send new brightness value
3168         updated->getValueObject(NS__SMARTAPI + "Brightness")->setValue(brightnessValue);
3169         Entity* updated2 = srAgent->setValueObject(updated, updated->getValueObject(NS__SMARTAPI + "Brightness"));
3170         updated->destroyCascade();
3171         updated2->destroyCascade();
3172
3173         // fetch brightness value again to see if it changed correctly
3174         Entity* updated3 = srAgent->getValueObject(e, brightness);
3175         int newValue = updated3->getValueObject(NS__SMARTAPI + "Brightness")->getValueAsInt();
3176         qDebug() << "Read:" << brightnessValue;
3177         updated3->destroyCascade();
3178
3179         if (brightnessValue != newValue) {
3180             qDebug() << "Standard RW test failed. Value (brightness) was not set correctly!";
3181             return false;
3182         }
3183
3184         // fetch power on state value
3185         Entity* updated4 = srAgent->getValueObject(e, e->getValueObject(RESOURCE__POWERONSTATE));
3186         powerValue = updated4->getValueObject(RESOURCE__POWERONSTATE)->getValueAsBoolean();
3187         updated4->destroyCascade();
3188
3189         // set new power on value
3190         powerValue = !powerValue;
3191
3192         // send new power on state value
3193         e->getValueObject(RESOURCE__POWERONSTATE)->setValue(powerValue);
3194         Entity* updated5 = srAgent->setValueObject(e, e->getValueObject(RESOURCE__POWERONSTATE));
3195         updated5->destroyCascade();
3196
3197         // fetch power on state value
3198         Entity* updated6 = srAgent->getValueObject(e, e->getValueObject(RESOURCE__POWERONSTATE));
3199         bool newPowerValue = updated6->getValueObject(RESOURCE__POWERONSTATE)->getValueAsBoolean();
3200         updated6->destroyCascade();
3201
3202         if (powerValue != newPowerValue) {
3203             qDebug() << "Standard RW test failed. Value (power on state) was not set correctly!";
3204             return false;
3205         }
3206
3207         e->destroyCascade();
3208     }
3209         delete srAgent;
3210
3211         */
3212     delete agent;
3213     qDebug() << "Standard RW test passed.";
3214     return true;
3215 }
3216
3217 bool serializeEmptyRdfListTest()
3218 {
3219         qDebug() << "Running serializeEmptyRdfListTest...";
3220
3221         DistanceDependentPriceSpecification* ddps = new DistanceDependentPriceSpecification();
3222         ddps->turtlePrint();
3223         ddps->destroyCascade();
3224         return true;
3225 }
3226
3227 bool serializeParseRouteTest()
3228 {
3229         qDebug() << "Running serializeParseRouteTest...";
3230         Route* r = new Route();
3231         r->addRoutePoint(new Coordinates(1.1, 2.2));
3232         r->addRoutePoint(new Coordinates(3.3, 4.4));
3233
3234         r->turtlePrint();
3235
3236         QString serialized = Tools::toString(r, SERIALIZATION__TURTLE);
3237         qDebug() << "Serialized:";
3238         //printf("%s\n", serialized.toLatin1().data());
3239         r->destroyCascade();
3240         qDebug() << serialized;
3241
3242         Route* parsed = (Route*)Tools::fromStringAsObj(serialized, SERIALIZATION__TURTLE);
3243     qDebug() << "Parsed2:";
3244         parsed->turtlePrint();
3245         parsed->destroyCascade();
3246         return true;
3247 }
3248
3249 int main(int argc, char *argv[])
3250 {
3251         srand(time(NULL));
3252
3253         QCoreApplication app(argc, argv);
3254
3255         //modelReadTest();
3256
3257     /*
3258
3259         qDebug() << "\n\nVARIANT TEST";
3260         if (!variantTest()) {
3261                 qDebug() << "\nVARIANT TEST FAILED!";
3262                 return -1;
3263         }
3264
3265     qDebug() << "\n\nSERIALIZE TEST";
3266         if (!serializeRequestTest()) {
3267                 qDebug() << "\nSERIALIZE TEST FAILED!";
3268                 return -1;
3269         }
3270
3271         qDebug() << "\n\nSHORT SERIALIZE PARSE TEST";
3272         if (!shortSerializeParseTest()) {
3273                 qDebug() << "\nSHORT SERIALIZE PARSE TEST FAILED!";
3274                 return -1;
3275         }
3276
3277         qDebug() << "\n\nAUTOMATIC SERIALIZE PARSE TEST";
3278         if (!automaticSerializeParseTest()) {
3279                 qDebug() << "\nAUTOMATIC SERIALIZE PARSE TEST FAILED!";
3280                 return -1;
3281         }
3282
3283         qDebug() << "\n\nLONG SERIALIZE PARSE TEST";
3284         if (!longSerializeParseTest()) {
3285                 qDebug() << "\nLONG SERIALIZE PARSE TEST FAILED!";
3286                 return -1;
3287         }
3288
3289         qDebug() << "\n\nNOTIFICATION TEST";
3290         if (!notificationTest()) {
3291                 qDebug() << "\nNOTIFICATION TEST FAILED!";
3292                 return -1;
3293         }
3294
3295 #if 0
3296         // FIXME implement this
3297         qDebug() << "\n\nHUGE DATA TEST";
3298         if (!hugeDataTest()) {
3299                 qDebug() << "\nHUGE DATA TEST FAILED!";
3300                 return -1;
3301         }
3302 #endif
3303
3304     qDebug() << "\n\nPHYSICAL ENTITY TEST";
3305         if (!physicalEntityTest()) {
3306                 qDebug() << "\nPHYSICAL ENTITY TEST FAILED!";
3307                 return -1;
3308         }
3309
3310         qDebug() << "\n\nMAPPING TEST";
3311         if (!listOfMapsTest()) {
3312                 qDebug() << "\nMAPPING TEST FAILED!";
3313                 return -1;
3314         }
3315
3316     qDebug() << "\n\nREGISTRATION TEST";
3317         if (!chargePlanRegistrationTest() ||
3318                         !encryptedRegistrationTest()) {
3319                 qDebug() << "\nREGISTRATION TEST FAILED!";
3320                 return -1;
3321         }
3322
3323         qDebug() << "\n\nROUTE FETCH TEST";
3324         if (!routeFetchTest()) {
3325                 qDebug() << "\nROUTE FETCH TEST FAILED!";
3326                 return -1;
3327     }
3328
3329 #if 0
3330         // FIXME this fails because server doesn't respond as expected
3331         qDebug() << "\n\nCHARGE PLAN FETCH TEST";
3332         if (!chargePlanFetchTest()) {
3333                 qDebug() << "\nCHARGE PLAN FETCH TEST FAILED!";
3334                 return -1;
3335         }
3336 #endif
3337
3338         /*qDebug() << "\n\nGATEWAY REGISTRATION TEST";
3339         if (!gatewayRegistrationTest()) {
3340                 qDebug() << "\nGATEWAY REGISTRATION TEST FAILED!";
3341                 return -1;
3342     }
3343
3344         qDebug() << "\n\nFAULTY ID TEST";
3345         if (!faultyIdTest()) {
3346                 qDebug() << "\nFAULTY ID TEST FAILED!";
3347                 return -1;
3348         }
3349
3350         qDebug() << "\n\nAVAILABILITY TEST";
3351         if (!availabilityTest()) {
3352                 qDebug() << "\nAVAILABILITY TEST FAILED!";
3353                 return -1;
3354         }
3355
3356 #if 0
3357         // FIXME this requires a suitable server in port 8099
3358         qDebug() << "\n\nROUTE REQUEST TEST";
3359         if (!routeRequestTest()) {
3360                 qDebug() << "\nROUTE REQUEST TEST FAILED!";
3361                 return -1;
3362         }
3363 #endif
3364
3365         qDebug() << "\n\nCRYPTO AND HASH TESTS";
3366         if (!simpleHashTest() ||
3367                         !asymmetricEncryptionTest() ||
3368                         !symmetricEncryptionTest() ||
3369                         !simpleSignatureTest() ||
3370                         !hashVerificationTest()) {
3371                 qDebug() << "\nSIMPLE SIGNATURE TEST FAILED!";
3372                 return -1;
3373         }
3374
3375         qDebug() << "\n\nCROSS SYSTEM CRYPTO TEST";
3376         if (!crossSystemDecryptionTest()) {
3377                 qDebug() << "\nCROSS SYSTEM CYRPTO TEST FAILED!";
3378                 return -1;
3379         }
3380
3381 #if 0
3382         //
3383         qDebug() << "\n\nKEY SERVER TESTS";propertyTest();
3384         if (!keyServerTest() ||
3385                         !keyGenerationTest() ||
3386                         !keyRevokationTest() ||
3387                         !keyUploadTest() ||
3388                         !keyEncryptionTest()) {
3389                 qDebug() << "\nKEY SERVER TESTS FAILED!";
3390                 return -1;
3391         }
3392 #endif
3393
3394 #if 0
3395         // FIXME this requires solar panel gateway in port 8080 and security broker in port 11372
3396         qDebug() << "\n\nSOLAR PANEL CLIENT TEST";
3397         if (!solarPanelClientTest()) {
3398                 qDebug() << "\nSOLAR PANEL CLIENT TEST FAILED!";
3399                 return -1;
3400         }
3401 #endif
3402
3403         qDebug() << "\n\nOFFERING TEST";
3404         if (!offeringTest()) {
3405                 qDebug() << "\nOFFERING TEST FAILED!";
3406                 return -1;
3407         }
3408
3409         qDebug() << "\n\nSHARING TEST";
3410         if (!sharingTest()) {
3411                 qDebug() << "\nSHARING TEST FAILED!";
3412                 return -1;
3413     }
3414
3415         qDebug() << "\n\nIDENTIFIER MANAGEMENT TEST";
3416         if (!identifierManagementTest()) {
3417                 qDebug() << "\nIDENTIFIER MANAGEMENT TEST FAILED!";
3418                 return -1;
3419         }
3420
3421
3422         qDebug() << "\n\nSTANDARD READ/WRITE TEST";
3423         if (!standardRWTest()) {
3424                 qDebug() << "\nSTANDARD READ/WRITE TEST FAILED!";
3425                 return -1;
3426     }
3427
3428         qDebug() << "\n\nENTITY MANAGED BY TEST";
3429         if (!entityManagedByTest()) {
3430                 qDebug() << "\nENTITY MANAGED BY TEST FAILED!";
3431                 return -1;
3432
3433         qDebug() << "\n\nENTITY COPY TEST";
3434         if (!entityCopyTest()) {
3435                 qDebug() << "\nENTITY COPY TEST FAILED!";
3436                 return -1;
3437         }
3438
3439         qDebug() << "\n\nPROPERTY LIST COPY TEST";
3440         if (!propertyListCopyTest()) {
3441                 qDebug() << "\nPROPERTY LIST COPY TEST FAILED!";
3442                 return -1;
3443         }
3444
3445         qDebug() << "\n\nPROPERTY LISTING TEST";
3446         if (!propertyListingTest()) {
3447                 qDebug() << "\nPROPERTY LISTING TEST FAILED!";
3448                 return -1;
3449         }
3450
3451         qDebug() << "\n\nPROPERTY TEST";
3452         if (!propertyTest()) {
3453                 qDebug() << "\nPROPERTY TEST FAILED!";
3454                 return -1;
3455         }
3456
3457         //------- LIST TESTS ------
3458         qDebug() << "\n\nLIST SERIALIZE / PARSE TEST";
3459         if (!listSerializeParseTest()) {
3460                 qDebug() << "\nLIST SERIALIZE / PARSE TEST FAILED!";
3461                 return -1;
3462         }
3463
3464         qDebug() << "\n\nLIST SPEED TEST";
3465         if (!listSpeedTest()) {
3466                 qDebug() << "\nLIST SPEED TEST FAILED!";
3467                 return -1;
3468         }
3469
3470         qDebug() << "\n\nBASEOBJECT LIST TEST";
3471         if (!baseObjectListSerializeParseTest()) {
3472                 qDebug() << "\nBASEOBJECT LIST TEST FAILED!";
3473                 return -1;
3474         }
3475
3476         //-------- TIMESERIES TESTS ------
3477         qDebug() << "\n\nSIMPLE TIMESERIES TEST";
3478         if (!simpleTimeSeriesTest()) {
3479                 qDebug() << "\nSIMPLE TIMESERIES FAILED!";
3480                 return -1;
3481         }
3482
3483         qDebug() << "\n\nVALUEOBJECT TIMESERIES TEST";
3484         if (!valueObjectTimeSeriesTest()) {
3485                 qDebug() << "\nVALUEOBJECT TIMESERIES TEST FAILED!";
3486                 return -1;
3487         }
3488
3489         qDebug() << "\n\nVALUEOBJECT TIMESERIES LIST SUBSTITUTE TEST";
3490         if (!substitutiveValueObjectTimeSeriesTest()) {
3491                 qDebug() << "\nVALUEOBJECT TIMESERIES LIST SUBSTITUTE TEST FAILED!";
3492                 return -1;
3493         }
3494
3495         qDebug() << "\n\nTIMESERIES BASE OBJECT TEST";
3496         if (!baseObjectTimeSeriesTest()) {
3497                 qDebug() << "\nTIMESERIES BASE OBJECT TEST FAILED!";
3498                 return -1;
3499         }
3500
3501         qDebug() << "\n\nTIMESERIES MANIPULATION TEST";
3502         if (!timeSeriesManipulationTest()) {
3503                 qDebug() << "\nTIMESERIES MANIPULATION TEST FAILED!";
3504                 return -1;
3505         }
3506
3507         qDebug() << "\n\nSUBSTITUTIVE TIMESERIES TEST";
3508         if (!substitutiveTimeSeriesParseTest()) {
3509                 qDebug() << "\nSUBSTITUTIVE TIMESERIES TEST FAILED!";
3510                 return -1;
3511         }
3512
3513 #if 0
3514         // FIXME this requires a server in port 8099
3515         qDebug() << "\n\nTIMESERIES FETCH AND COMPATIBILITY TEST";
3516         if (!networkTimeSeriesTest()) {
3517                 qDebug() << "\nTIMESERIES FETCH AND COMPATIBILITY TEST FAILED!";
3518                 return -1;
3519         }
3520
3521 #endif
3522
3523
3524         //-------- GEO TESTS ------
3525         qDebug() << "\n\nWAYPOINTS TEST";
3526         if (!waypointsTest()) {
3527                 qDebug() << "\nWAYPOINTS TEST FAILED!";
3528                 return -1;
3529         }
3530
3531         qDebug() << "\n\nROUTE TEST";
3532         if (!routeTest()) {
3533                 qDebug() << "\nWAYPOINTS TEST FAILED!";
3534                 return -1;
3535         }
3536
3537         //-------- REQUEST TESTS ------
3538         qDebug() << "\n\nREQUEST TEST";
3539         if (!propertyRequestTest()) {
3540                 qDebug() << "\nREQUEST TEST FAILED!";
3541                 return -1;
3542         }
3543
3544         qDebug() << "\n\TIMESERIES RESPONSE TEST";
3545         if (!timeseriesResponseTest()) {
3546                 qDebug() << "\TIMESERIES RESPONSE TEST FAILED!";
3547                 return -1;
3548         }
3549
3550         //-------- SIMULTANEOUS MODELS ------
3551         qDebug() << "\n\nMULTI-PARSE TEST";
3552         if (!multiParseTest()) {
3553                 qDebug() << "\nMULTI-PARSE TEST FAILED!";
3554                 return -1;
3555         }
3556
3557
3558         //-------- CHECKSUMS ------
3559         qDebug() << "\n\nBASIC CHECKSUM TEST";
3560         if (!basicChecksumTest()) {
3561                 qDebug() << "\nnBASIC CHECKSUM TEST FAILED!";
3562                 return -1;
3563         }
3564         qDebug() << "\n\nPARSED CHECKSUM TEST";
3565         if (!parsedChecksumTest()) {
3566                 qDebug() << "\nPARSED CHECKSUM TEST FAILED!";
3567                 return -1;
3568         }
3569         qDebug() << "\n\nCROSS CHECKSUM TEST";
3570         if (!crossChecksumTest()) {
3571                 qDebug() << "\nCROSS CHECKSUM TEST FAILED!";
3572                 return -1;
3573         }
3574
3575
3576     //-------- PRICING AND TRADING ------
3577         qDebug() << "\n\nBASIC PRICE SPEC TEST";
3578         if (!priceSpecificationSerializeParseTest()) {
3579                 qDebug() << "\nBASIC PRICE SPEC TEST FAILED!";
3580                 return -1;
3581         }
3582     //currencyConversionTest();
3583
3584         //registrationTest();
3585         //registrationSearchTest();
3586
3587         qDebug() << "\n\nSERIALIZE PARSE SIGNED RESPONSE TEST";
3588         if (!serializeParseSignedResponseTest()) {
3589                 qDebug() << "\nSERIALIZE PARSE SIGNED RESPONSE TEST FAILED!";
3590                 return -1;
3591         }
3592
3593         qDebug() << "\n\nSERIALIZE AN EMPTY RDF LIST TEST";
3594         if (!serializeEmptyRdfListTest()) {
3595