0d509acdefff176ceb199a0704d604facc5f5332
[framework/web/wrt-installer.git] / src_wearable / jobs / widget_install / manifest.cpp
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    manifest.cpp
18  * @author  Mariusz Domanski (m.domanski@samsung.com)
19  */
20
21 #include "manifest.h"
22 #include "libxml_utils.h"
23 #include <widget_install/task_manifest_file.h>
24 #include <dpl/foreach.h>
25 #include <installer_log.h>
26
27 namespace Jobs {
28 namespace WidgetInstall {
29 void writeElement(xmlTextWriterPtr writer, const char * name, DPL::String body)
30 {
31     int state = xmlTextWriterWriteElement(writer, BAD_CAST name,
32                                           BAD_CAST DPL::ToUTF8String(
33                                               body).c_str());
34     if (state < 0) {
35         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteElement failed");
36     }
37 }
38
39 void writeText(xmlTextWriterPtr writer, DPL::String text)
40 {
41     int state = xmlTextWriterWriteString(writer,
42                                          BAD_CAST DPL::ToUTF8String(text).c_str());
43     if (state < 0) {
44         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteText failed");
45     }
46 }
47
48 void writeElement(xmlTextWriterPtr writer, const char * name, const char * body)
49 {
50     int state = xmlTextWriterWriteElement(writer, BAD_CAST name, BAD_CAST body);
51     if (state < 0) {
52         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterWriteElement failed");
53     }
54 }
55
56 void writeElementWithOneAttribute(xmlTextWriterPtr writer,
57                                   const char * name,
58                                   DPL::String body,
59                                   const char * nameAttr,
60                                   DPL::String bodyAttr,
61                                   bool condition = true)
62 {
63     startElement(writer, name);
64     writeAttribute(writer, nameAttr, bodyAttr, condition);
65     writeText(writer, body);
66     endElement(writer);
67 }
68
69 void startElement(xmlTextWriterPtr writer, const char * name)
70 {
71     int state = xmlTextWriterStartElement(writer, BAD_CAST name);
72     if (state < 0) {
73         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterStartElement failed");
74     }
75 }
76
77 void endElement(xmlTextWriterPtr writer)
78 {
79     int state = xmlTextWriterEndElement(writer);
80     if (state < 0) {
81         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterEndElement failed");
82     }
83 }
84
85 void writeAttribute(xmlTextWriterPtr writer,
86                     const char * name,
87                     DPL::String body,
88                     bool condition = true)
89 {
90     if (!condition) {
91         return;
92     }
93     int state = xmlTextWriterWriteAttribute(writer, BAD_CAST name,
94                                             BAD_CAST DPL::ToUTF8String(
95                                                 body).c_str());
96     if (state < 0) {
97         ThrowMsg(LibxmlUtils::Libxml2Error,
98                  "xmlTextWriterWriteAttribute failed");
99     }
100 }
101
102 void writeAttribute(xmlTextWriterPtr writer,
103                     const char * name,
104                     const char * body,
105                     bool condition = true)
106 {
107     if (!condition) {
108         return;
109     }
110     int state = xmlTextWriterWriteAttribute(writer,
111                                             BAD_CAST name,
112                                             BAD_CAST body);
113     if (state < 0) {
114         ThrowMsg(LibxmlUtils::Libxml2Error,
115                  "xmlTextWriterWriteAttribute failed");
116     }
117 }
118
119 void Manifest::generate(DPL::String filename)
120 {
121     xmlTextWriterPtr writer;
122     int state;
123
124     //compression set to 0
125     writer = xmlNewTextWriterFilename(DPL::ToUTF8String(filename).c_str(), 0);
126
127     if (writer == NULL) {
128         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlNewTextWriterFilename failed");
129     }
130     state = xmlTextWriterSetIndent(writer, 1);
131     if (state < 0) {
132         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterSetIndent failed");
133     }
134
135     state = xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
136     if (state < 0) {
137         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterStartDocument failed");
138     }
139     this->serialize(writer);
140     state = xmlTextWriterEndDocument(writer);
141     if (state < 0) {
142         ThrowMsg(LibxmlUtils::Libxml2Error, "xmlTextWriterEndDocument failed");
143     }
144     if (writer != NULL) {
145         xmlFreeTextWriter(writer);
146         writer = NULL;
147     }
148 }
149
150 void Manifest::serialize(xmlTextWriterPtr writer)
151 {
152     startElement(writer, "manifest");
153     {
154         writeAttribute(writer, "xmlns", "http://tizen.org/ns/packages");
155         writeAttribute(writer, "package", this->package);
156         writeAttribute(writer, "type", this->type);
157         writeAttribute(writer, "version", this->version);
158         if (!!this->installLocation) {
159             writeAttribute(writer, "install-location", (*this->installLocation));
160         }
161         writeAttribute(writer, "storeclient-id", this->storeClientId,
162                 !this->storeClientId.empty());
163         writeAttribute(writer, "csc_path", this->cscPath,
164                 !this->cscPath.empty());
165
166         FOREACH(l, this->label)
167         {
168             writeElementWithOneAttribute(writer, "label", l->getString(),
169                                          "xml:lang", l->getLang(), l->hasLang());
170         }
171         FOREACH(i, this->icon)
172         {
173             writeElementWithOneAttribute(writer, "icon", i->getString(),
174                                          "xml:lang", i->getLang(), i->hasLang());
175         }
176         FOREACH(a, this->author)
177         {
178             a->serialize(writer);
179         }
180         FOREACH(d, this->description)
181         {
182             writeElementWithOneAttribute(writer, "description", d->getString(),
183                                          "xml:lang", d->getLang(), d->hasLang());
184         }
185         //FOREACH(c, this->compatibility) { c->serialize(writer); }
186         //FOREACH(d, this->deviceProfile) { d->serialize(writer); }
187 #ifdef SERVICE_ENABLED
188         FOREACH(s, this->serviceApplication) {
189             s->serialize(writer);
190         }
191 #endif
192         FOREACH(u, this->uiApplication) {
193             u->serialize(writer);
194         }
195 #ifdef IME_ENABLED
196         FOREACH(i, this->imeApplication) {
197             i->serialize(writer);
198         }
199 #endif
200         //FOREACH(f, this->font) { f->serialize(writer); }
201 #ifdef DBOX_ENABLED
202         FOREACH(l, this->livebox) {
203             l->serialize(writer);
204         }
205 #endif
206         FOREACH(acc, this->account)
207         {
208             acc->serialize(writer);
209         }
210
211         if (!this->privileges.isEmpty()) {
212             this->privileges.serialize(writer);
213         }
214     }
215     endElement(writer);
216 }
217
218 void Author::serialize(xmlTextWriterPtr writer)
219 {
220     startElement(writer, "author");
221     writeAttribute(writer, "email", this->email, !this->email.empty());
222     writeAttribute(writer, "href", this->href, !this->href.empty());
223     writeAttribute(writer, "xml:lang", this->lang, !this->lang.empty());
224     writeText(writer, body);
225     endElement(writer);
226 }
227
228 void UiApplication::serialize(xmlTextWriterPtr writer)
229 {
230     startElement(writer, "ui-application");
231     writeAttribute(writer, "appid", this->appid);
232     writeAttribute(writer, "exec", this->exec);
233     if (!!this->multiple) {
234         writeAttribute(writer, "multiple", (*this->multiple) ? "true" : "false");
235     }
236     if (!!this->nodisplay) {
237         writeAttribute(writer,
238                        "nodisplay",
239                        (*this->nodisplay) ? "true" : "false");
240     }
241     if (!!this->taskmanage) {
242         writeAttribute(writer,
243                        "taskmanage",
244                        (*this->taskmanage) ? "true" : "false");
245     }
246     writeAttribute(writer, "type", this->type);
247     writeAttribute(writer, "extraid", this->extraid);
248     if (!!this->categories) {
249         writeAttribute(writer, "categories", (*this->categories));
250     }
251     FOREACH(l, this->label)
252     {
253         writeElementWithOneAttribute(writer, "label",
254                                      l->getString(), "xml:lang",
255                                      l->getLang(), l->hasLang());
256     }
257     FOREACH(i, this->icon)
258     {
259         startElement(writer, "icon");
260         {
261             writeAttribute(writer, "xml:lang", i->getLang(), i->hasLang());
262             writeAttribute(writer, "section", "small", i->isSmall());
263             writeText(writer, i->getString());
264         }
265         endElement(writer);
266     }
267     FOREACH(a, this->appControl)
268     {
269         a->serialize(writer);
270     }
271     FOREACH(c, this->appCategory)
272     {
273         startElement(writer, "category");
274         writeAttribute(writer, "name", *c);
275         endElement(writer);
276     }
277     FOREACH(m, this->metadata) {
278         m->serialize(writer);
279     }
280     endElement(writer);
281 }
282
283 #ifdef IME_ENABLED
284 void ImeApplication::serialize(xmlTextWriterPtr writer)
285 {
286     startElement(writer, "ime");
287     writeAttribute(writer, "appid", this->appid);
288     {
289         startElement(writer, "uuid");
290         writeText(writer, this->uuid);
291         endElement(writer);
292         FOREACH(l, this->label)
293         {
294             writeElementWithOneAttribute(writer, "label", l->getString(), "xml:lang", l->getLang(), l->hasLang());
295         }
296         startElement(writer, "languages");
297         {
298             FOREACH(g, this->language)
299             {
300                 startElement(writer, "language");
301                 writeText(writer, *g);
302                 endElement(writer);
303             }
304         }
305         endElement(writer);
306         startElement(writer, "type");
307         writeText(writer, this->iseType);
308         endElement(writer);
309         startElement(writer, "options");
310         {
311             FOREACH(o, this->option)
312             {
313                 startElement(writer, "option");
314                 writeText(writer, *o);
315                 endElement(writer);
316             }
317         }
318         endElement(writer);
319     }
320     endElement(writer);
321 }
322 #endif
323
324 #ifdef SERVICE_ENABLED
325 void ServiceApplication::serialize(xmlTextWriterPtr writer)
326 {
327     startElement(writer, "ui-application");
328     writeAttribute(writer, "component-type", this->component);
329     writeAttribute(writer, "auto-restart", (!!this->autoRestart && (*this->autoRestart)) ? "true" : "false");
330     writeAttribute(writer, "on-boot", (!!this->onBoot && (*this->onBoot)) ? "true" : "false");
331     writeAttribute(writer, "appid", this->appid);
332     writeAttribute(writer, "exec", this->exec);
333     writeAttribute(writer, "extraid", this->extraid);
334     if (!!this->nodisplay) {
335         writeAttribute(writer, "nodisplay", (*this->nodisplay) ? "true" : "false");
336     }
337     if (!!this->multiple) {
338         writeAttribute(writer, "multiple", (*this->multiple) ? "true" : "false");
339     }
340     writeAttribute(writer, "type", this->type);
341     if (!!this->taskmanage) {
342         writeAttribute(writer, "taskmanage", (*this->taskmanage) ? "true" : "false");
343     }
344     if (!!this->categories) {
345         writeAttribute(writer, "categories", (*this->categories));
346     }
347     FOREACH(l, this->label)
348     {
349         writeElementWithOneAttribute(writer, "label",
350                                      l->getString(), "xml:lang",
351                                      l->getLang(), l->hasLang());
352     }
353     FOREACH(i, this->icon)
354     {
355         writeElementWithOneAttribute(writer, "icon", i->getString(), "xml:lang",
356                                      i->getLang(), i->hasLang());
357     }
358     FOREACH(a, this->appControl)
359     {
360         a->serialize(writer);
361     }
362     FOREACH(c, this->appCategory)
363     {
364         startElement(writer, "category");
365         writeAttribute(writer, "name", *c);
366     endElement(writer);
367 }
368     FOREACH(m, this->metadata) {
369         m->serialize(writer);
370     }
371     endElement(writer);
372 }
373 #endif
374
375 void AppControl::serialize(xmlTextWriterPtr writer)
376 {
377     startElement(writer, "app-control");
378     FOREACH(o, this->operation)
379     {
380         startElement(writer, "operation");
381         writeAttribute(writer, "name", *o);
382         endElement(writer);
383     }
384     FOREACH(u, this->uri)
385     {
386         startElement(writer, "uri");
387         writeAttribute(writer, "name", *u);
388         endElement(writer);
389     }
390     FOREACH(m, this->mime)
391     {
392         startElement(writer, "mime");
393         writeAttribute(writer, "name", *m);
394         endElement(writer);
395     }
396     endElement(writer);
397 }
398
399 #ifdef DBOX_ENABLED
400 void LiveBox::serialize(xmlTextWriterPtr writer)
401 {
402     startElement(writer, "livebox");
403     if (!this->liveboxId.empty()) {
404         writeAttribute(writer, "appid", this->liveboxId);
405     }
406
407     if (!this->primary.empty()) {
408         writeAttribute(writer, "primary", this->primary);
409     }
410
411     if (!this->updatePeriod.empty()) {
412         writeAttribute(writer, "period", this->updatePeriod);
413     }
414
415     writeAttribute(writer, "abi", "html");
416     writeAttribute(writer, "network", "true");
417     writeAttribute(writer, "nodisplay", "false");
418
419     if (!this->label.empty()) {
420         int defaultLabelChk = 0;
421         FOREACH(m, this->label)
422         {
423             std::pair<DPL::String, DPL::String> boxLabel = *m;
424             startElement(writer, "label");
425             if (!boxLabel.first.empty()) {
426                 writeAttribute(writer, "xml:lang", boxLabel.first);
427             } else {
428                 defaultLabelChk++;
429             }
430             writeText(writer, boxLabel.second);
431             endElement(writer);
432         }
433         if(!defaultLabelChk) {
434             startElement(writer, "label");
435             writeText(writer, DPL::FromUTF8String("NO NAME"));
436             endElement(writer);
437         }
438     }
439     if (!this->icon.empty()) {
440         startElement(writer, "icon");
441         writeText(writer, this->icon);
442         endElement(writer);
443     }
444
445     if (!this->autoLaunch.empty()) {
446         startElement(writer, "launch");
447         writeText(writer, this->autoLaunch);
448         endElement(writer);
449     }
450
451     if (!this->box.boxSrc.empty() &&
452         !this->box.boxMouseEvent.empty() &&
453         !this->box.boxSize.empty())
454     {
455         startElement(writer, "box");
456         writeAttribute(writer, "type", "buffer");
457         writeAttribute(writer, "mouse_event", this->box.boxMouseEvent);
458         writeAttribute(writer, "touch_effect", this->box.boxTouchEffect);
459
460         FOREACH(it, this->box.boxSize)
461         {
462             startElement(writer, "size");
463             if (!(*it).m_preview.empty()) {
464                 writeAttribute(writer, "preview", (*it).m_preview);
465             }
466             if (!(*it).m_useDecoration.empty()) {
467                 writeAttribute(writer, "need_frame", (*it).m_useDecoration);
468             } else {
469                 // default value of use-decoration is "true"
470                 writeAttribute(writer, "need_frame", DPL::String(L"true"));
471             }
472
473             writeText(writer, (*it).m_size);
474             endElement(writer);
475         }
476
477         startElement(writer, "script");
478         writeAttribute(writer, "src", this->box.boxSrc);
479         endElement(writer);
480
481         endElement(writer);
482
483         if (!this->box.pdSrc.empty() &&
484             !this->box.pdWidth.empty() &&
485             !this->box.pdHeight.empty())
486         {
487             startElement(writer, "pd");
488             writeAttribute(writer, "type", "buffer");
489
490             startElement(writer, "size");
491             DPL::String pdSize = this->box.pdWidth + DPL::String(L"x") +
492                 this->box.pdHeight;
493             writeText(writer, pdSize);
494             endElement(writer);
495
496             startElement(writer, "script");
497             writeAttribute(writer, "src", this->box.pdSrc);
498             endElement(writer);
499
500             endElement(writer);
501         }
502     }
503
504     endElement(writer);
505 }
506 #endif
507
508 void Account::serialize(xmlTextWriterPtr writer)
509 {
510     startElement(writer, "account");
511     {
512         startElement(writer, "account-provider");
513         writeAttribute(writer, "appid", this->provider.appid);
514         writeAttribute(writer, "multiple-accounts-support",
515                 this->provider.multiAccount);
516
517         FOREACH(i, this->provider.icon)
518         {
519             startElement(writer, "icon");
520             writeAttribute(writer, "section", i->first);
521             writeText(writer, i->second);
522             endElement(writer);
523         }
524
525         bool setDefaultLang = false;
526         FOREACH(n, this->provider.name)
527         {
528             if (!setDefaultLang && n->getLang() == L"en-gb") {
529                 writeElement(writer, "label", n->getString());
530                 setDefaultLang = true;
531             }
532             writeElementWithOneAttribute(writer, "label",
533                     n->getString(), "xml:lang",
534                     n->getLang(), n->hasLang());
535         }
536         if (!setDefaultLang) {
537             writeElement(writer, "label", this->provider.name.begin()->getString());
538         }
539
540         FOREACH(c, this->provider.capability)
541         {
542             startElement(writer, "capability");
543             writeText(writer, *c);
544             endElement(writer);
545         }
546         endElement(writer);
547     }
548     endElement(writer);
549 }
550
551 void Privilege::serialize(xmlTextWriterPtr writer)
552 {
553     startElement(writer, "privileges");
554     {
555         FOREACH(it, this->name)
556         {
557             startElement(writer, "privilege");
558             writeText(writer, *it);
559             endElement(writer);
560         }
561     }
562     endElement(writer);
563 }
564
565 void Metadata::serialize(xmlTextWriterPtr writer)
566 {
567     startElement(writer, "metadata");
568     writeAttribute(writer, "key", *this->key);
569     if (!!this->value) {
570         writeAttribute(writer, "value", *this->value);
571     }
572     endElement(writer);
573 }
574 } //namespace Jobs
575 } //namespace WidgetInstall