[Release] wrt-installer_0.1.101
[framework/web/wrt-installer.git] / src / configuration_parser / widget_parser.cpp
1 /*
2  * Copyright (c) 2011 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  * This file  have been implemented in compliance with  W3C WARP SPEC.
18  * but there are some patent issue between  W3C WARP SPEC and APPLE.
19  * so if you want to use this file, refer to the README file in root directory
20  */
21 /**
22  * @file        widget_parser.cpp
23  * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
24  * @version     0.1
25  * @brief
26  */
27 #include "widget_parser.h"
28 #include "ignoring_parser.h"
29 #include "deny_all_parser.h"
30 #include <dpl/wrt-dao-ro/config_parser_data.h>
31 #include "libiriwrapper.h"
32 #include <dpl/utils/warp_iri.h>
33 #include <dpl/utils/mime_type_utils.h>
34 #include <language_subtag_rst_tree.h>
35
36 #include <iri.h>
37 #include <dpl/log/log.h>
38 #include <dpl/fast_delegate.h>
39 #include <dpl/foreach.h>
40 #include <dpl/scoped_ptr.h>
41 #include <pcrecpp.h>
42 #include <algorithm>
43 #include <string>
44 #include <cstdio>
45 #include <cerrno>
46 #include <climits>
47 #include <cmath>
48 #include <cstdlib>
49 #include <locale>
50
51 using namespace WrtDB;
52
53 namespace Unicode {
54 static const DPL::String UTF_LRE = L"\x0202a";
55 static const DPL::String UTF_LRO = L"\x0202d";
56 static const DPL::String UTF_RLE = L"\x0202b";
57 static const DPL::String UTF_RLO = L"\x0202e";
58 static const DPL::String UTF_PDF = L"\x0202c";
59
60 Direction ParseDirAttribute(const XmlAttribute& attribute)
61 {
62     Assert(L"dir" == attribute.name);
63     if (L"ltr" == attribute.value) {
64         return LRE;
65     } else if (L"rtl" == attribute.value) {
66         return RLE;
67     } else if (L"lro" == attribute.value) {
68         return LRO;
69     } else if (L"rlo" == attribute.value) {
70         return RLO;
71     } else {
72         LogWarning("dir attribute has wrong value:" << attribute.value);
73         return EMPTY;
74     }
75 }
76
77 void UpdateTextWithDirectionMark(Direction direction,
78                                  DPL::String* text)
79 {
80     Assert(text);
81     switch (direction) {
82     case RLO:
83         *text = UTF_RLO + *text + UTF_PDF;
84         break;
85     case RLE:
86         *text = UTF_RLE + *text + UTF_PDF;
87         break;
88     case LRE:
89         *text = UTF_LRE + *text + UTF_PDF;
90         break;
91     case LRO:
92         *text = UTF_LRO + *text + UTF_PDF;
93         break;
94     case EMPTY:
95         break;
96     default:
97         Assert(false);
98         break;
99     }
100 }
101 } // namespace Unicode
102
103 class InnerElementsParser : public ElementParser
104 {
105   public:
106     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
107                                         const DPL::String& /*name*/)
108     {
109         return DPL::MakeDelegate(this, &InnerElementsParser::Other);
110     }
111
112     virtual void Accept(const Element& /*element*/)
113     {}
114
115     virtual void Accept(const Text& text)
116     {
117         if (m_text.IsNull()) {
118             m_text = text;
119         } else {
120             m_text->value += text.value;
121         }
122     }
123
124     virtual void Accept(const XmlAttribute& attribute)
125     {
126         if (attribute.name == L"dir") {
127             m_textDirection = Unicode::ParseDirAttribute(attribute);
128         }
129     }
130
131     virtual void Verify()
132     {
133         if (!m_text.IsNull()) {
134             Unicode::UpdateTextWithDirectionMark(m_textDirection,
135                                                  &m_text->value);
136             m_parentParser->Accept(*m_text);
137         }
138     }
139
140     InnerElementsParser(ElementParserPtr parent) :
141         m_parentParser(parent),
142         m_textDirection(Unicode::EMPTY)
143     {}
144
145     ElementParserPtr Other()
146     {
147         return ElementParserPtr(new InnerElementsParser(
148                                     std::static_pointer_cast<ElementParser>(
149                                         shared_from_this())));
150     }
151
152   private:
153     DPL::Optional<Text> m_text;
154     ElementParserPtr m_parentParser;
155     Unicode::Direction m_textDirection;
156 };
157
158 class NameParser : public ElementParser
159 {
160   public:
161     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
162                                         const DPL::String& /*name*/)
163     {
164         return DPL::MakeDelegate(this, &NameParser::Other);
165     }
166
167     virtual void Accept(const Element& element)
168     {
169         m_lang = element.lang;
170         m_name = L"";
171     }
172
173     virtual void Accept(const Text& text)
174     {
175         if (m_name.IsNull()) {
176             m_name = text.value;
177         } else {
178             *m_name += text.value;
179         }
180     }
181
182     virtual void Accept(const XmlAttribute& attribute)
183     {
184         if (attribute.name == L"short") {
185             if (m_shortName.IsNull()) {
186                 m_shortName = attribute.value;
187             }
188         } else if (attribute.name == L"dir") {
189             m_textDirection = Unicode::ParseDirAttribute(attribute);
190         }
191     }
192
193     virtual void Verify()
194     {
195         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
196         if (data.name.IsNull()) {
197             NormalizeString(m_name);
198             NormalizeString(m_shortName);
199             if (!m_name.IsNull()) {
200                 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
201             }
202             data.name = m_name;
203             if (!m_shortName.IsNull()) {
204                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
205                                                      &*m_shortName);
206             }
207             data.shortName = m_shortName;
208         }
209     }
210
211     NameParser(Unicode::Direction direction,
212                ConfigParserData& data) :
213         m_data(data),
214         m_textDirection(direction)
215     {}
216
217     ElementParserPtr Other()
218     {
219         return ElementParserPtr(new InnerElementsParser(
220                                     std::static_pointer_cast<ElementParser>(
221                                         shared_from_this())));
222     }
223
224   private:
225     ConfigParserData& m_data;
226     DPL::OptionalString m_name;
227     DPL::OptionalString m_shortName;
228     DPL::OptionalString m_dir;
229     DPL::String m_lang;
230     Unicode::Direction m_textDirection;
231 };
232
233 class AccessParser : public ElementParser
234 {
235   public:
236     enum StandardType
237     {
238         STANDARD_TYPE_NONE,
239         STANDARD_TYPE_WARP
240     };
241
242     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
243                                         const DPL::String& /*name*/)
244     {
245         return DPL::MakeDelegate(this, &AccessParser::Other);
246     }
247
248     virtual void Accept(const Element& element)
249     {
250         // for tizen web apps WARP should be used
251         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
252             element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
253         {
254             m_standardType = STANDARD_TYPE_WARP;
255         }
256     }
257
258     virtual void Accept(const Text& /*text*/)
259     {}
260
261     void AcceptWac(const XmlAttribute& attribute)
262     {
263         if (attribute.name == L"origin") {
264             m_strIRIOrigin = attribute.value;
265             NormalizeString(m_strIRIOrigin);
266         } else if (attribute.name == L"subdomains") {
267             DPL::String normalizedValue = attribute.value;
268             NormalizeString(normalizedValue);
269
270             if (normalizedValue == L"true") {
271                 m_bSubDomainAccess = true;
272             } else if (normalizedValue == L"false") {
273                 m_bSubDomainAccess = false;
274             }
275         }
276     }
277
278     virtual void Accept(const XmlAttribute& attribute)
279     {
280         switch (m_standardType) {
281         case STANDARD_TYPE_WARP:
282             AcceptWac(attribute);
283             break;
284         default:
285             LogError("Error in Access tag - unknown standard.");
286             break;
287         }
288     }
289
290     void VerifyWac()
291     {
292         WarpIRI iri;
293         iri.set(m_strIRIOrigin, false);
294
295         if (!iri.isAccessDefinition()) {
296             LogWarning("Access list element: " <<
297                        m_strIRIOrigin <<
298                        " is not acceptable by WARP" <<
299                        "standard and will be ignored!");
300             return;
301         }
302
303         if(m_strIRIOrigin == L"*") //wildcard match means yes for subdomains
304         {
305             m_bSubDomainAccess = true;
306         }
307
308         ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
309                                                 m_bSubDomainAccess);
310         //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
311         m_data.accessInfoSet.insert(accessInfo);
312     }
313
314     virtual void Verify()
315     {
316         switch (m_standardType) {
317         case STANDARD_TYPE_WARP:
318             VerifyWac();
319             break;
320         default:
321             LogError("Error in Access tag - unknown standard.");
322             break;
323         }
324     }
325
326     AccessParser(ConfigParserData& data) :
327         ElementParser(),
328         m_bSubDomainAccess(false),
329         m_standardType(STANDARD_TYPE_NONE),
330         m_network(false),
331         m_data(data)
332     {}
333
334     ElementParserPtr Other()
335     {
336         return ElementParserPtr(new InnerElementsParser(
337                                     ElementParserPtr(shared_from_this())));
338     }
339
340   private:
341     DPL::String m_strIRIOrigin;
342     bool m_bSubDomainAccess;
343     StandardType m_standardType;
344     bool m_network;
345     ConfigParserData& m_data;
346 };
347
348 class DescriptionParser : public ElementParser
349 {
350   public:
351     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
352                                         const DPL::String& /*name*/)
353     {
354         return DPL::MakeDelegate(this, &DescriptionParser::Other);
355     }
356
357     virtual void Accept(const Element& element)
358     {
359         m_lang = element.lang;
360         m_description = L"";
361     }
362
363     ElementParserPtr Other()
364     {
365         return ElementParserPtr(new InnerElementsParser(
366                                     std::static_pointer_cast<ElementParser>(
367                                         shared_from_this())));
368     }
369
370     virtual void Accept(const Text& text)
371     {
372         if (m_description.IsNull()) {
373             m_description = text.value;
374         } else {
375             *m_description += text.value;
376         }
377     }
378
379     virtual void Accept(const XmlAttribute& attribute)
380     {
381         if (attribute.name == L"dir") {
382             m_textDirection = Unicode::ParseDirAttribute(attribute);
383         }
384     }
385
386     virtual void Verify()
387     {
388         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
389         if (data.description.IsNull()) {
390             if (!m_description.IsNull()) {
391                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
392                                                      &*m_description);
393             }
394             data.description = m_description;
395         }
396     }
397
398     DescriptionParser(Unicode::Direction direction,
399                       ConfigParserData& data) :
400         m_data(data),
401         m_lang(),
402         m_description(),
403         m_textDirection(direction)
404     {}
405
406   private:
407     ConfigParserData& m_data;
408     DPL::String m_lang;
409     DPL::OptionalString m_description;
410     Unicode::Direction m_textDirection;
411 };
412
413 class AuthorParser : public ElementParser
414 {
415   public:
416     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
417                                         const DPL::String& /*name*/)
418     {
419         return DPL::MakeDelegate(this, &AuthorParser::Other);
420     }
421
422     AuthorParser(Unicode::Direction direction,
423                  ConfigParserData& data) :
424         m_data(data),
425         m_textDirection(direction)
426     {}
427
428     virtual void Accept(const Element& /*element*/)
429     {
430         m_authorName = L"";
431     }
432
433     virtual void Accept(const Text& text)
434     {
435         *(m_authorName) += text.value;
436     }
437
438     virtual void Accept(const XmlAttribute& attribute)
439     {
440         if (attribute.name == L"href") {
441             //Validate href IRI and ignore it if invalid
442             //See also test: ta-argMozRiC-an
443             LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
444             if (iri.Validate()) {
445                 m_authorHref = attribute.value;
446             }
447         } else if (attribute.name == L"email") {
448             m_authorEmail = attribute.value;
449         } else if (attribute.name == L"dir") {
450             m_textDirection = Unicode::ParseDirAttribute(attribute);
451         }
452     }
453
454     virtual void Verify()
455     {
456         if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) {
457             NormalizeString(m_authorName);
458             NormalizeString(m_authorHref);
459             NormalizeString(m_authorEmail);
460             if (!!m_authorName) {
461                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
462                                                      &*m_authorName);
463                 m_data.authorName = m_authorName;
464             }
465             if (!!m_authorHref) {
466                 m_data.authorHref = m_authorHref;
467             }
468             if (!!m_authorEmail) {
469                 m_data.authorEmail = m_authorEmail;
470             }
471         }
472     }
473
474     ElementParserPtr Other()
475     {
476         return ElementParserPtr(new InnerElementsParser(
477                                     std::static_pointer_cast<ElementParser>(
478                                         shared_from_this())));
479     }
480
481   private:
482     ConfigParserData& m_data;
483     DPL::OptionalString m_authorEmail;
484     DPL::OptionalString m_authorHref;
485     DPL::OptionalString m_authorName;
486     Unicode::Direction m_textDirection;
487 };
488
489 class LicenseParser : public ElementParser
490 {
491   public:
492     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
493                                         const DPL::String& /*name*/)
494     {
495         return DPL::MakeDelegate(this, &LicenseParser::Other);
496     }
497
498     LicenseParser(Unicode::Direction direction,
499                   ConfigParserData& data) :
500         m_data(data),
501         m_ignore(true),
502         m_textDirection(direction)
503     {}
504
505     virtual void Accept(const Element& element)
506     {
507         if (m_license.IsNull()) {
508             m_lang = element.lang;
509             m_license = L"";
510             m_ignore = false;
511         }
512     }
513
514     virtual void Accept(const Text& text)
515     {
516         if (!m_ignore) {
517             *m_license += text.value;
518         }
519     }
520
521     virtual void Accept(const XmlAttribute& attribute)
522     {
523         if (!m_ignore) {
524             if (attribute.name == L"href" && m_licenseHref.IsNull()) {
525                 m_licenseHref = attribute.value;
526             } else if (attribute.name == L"file" && m_licenseFile.IsNull()) {
527                 m_licenseFile = attribute.value;
528             } else if (attribute.name == L"dir") {
529                 m_textDirection = Unicode::ParseDirAttribute(attribute);
530             }
531         }
532     }
533
534     virtual void Verify()
535     {
536         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
537         if (data.license.IsNull()) {
538             if (!m_license.IsNull()) {
539                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
540                                                      &*m_license);
541             }
542             data.license = m_license;
543             data.licenseHref = m_licenseHref;
544             data.licenseFile = m_licenseFile;
545         }
546     }
547
548     ElementParserPtr Other()
549     {
550         return ElementParserPtr(new InnerElementsParser(
551                                     ElementParserPtr(shared_from_this())));
552     }
553
554   private:
555     ConfigParserData& m_data;
556     DPL::String m_lang;
557     bool m_ignore;
558
559     DPL::OptionalString m_license;
560     DPL::OptionalString m_licenseFile;
561     DPL::OptionalString m_licenseHref;
562     Unicode::Direction m_textDirection;
563 };
564
565 class IconParser : public ElementParser
566 {
567     DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
568
569   public:
570     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
571                                         const DPL::String& /*name*/)
572     {
573         return &IgnoringParser::Create; //ignore unknown according to w3c
574     }
575
576     IconParser(ConfigParserData& data) : ElementParser(),
577         m_data(data)
578     {}
579
580     virtual void Accept(const Element& /*element*/)
581     {}
582
583     virtual void Accept(const XmlAttribute& attribute)
584     {
585         if (attribute.name == L"src") {
586             if (attribute.value.size() > 0) {
587                 m_src = attribute.value;
588             }
589         } else if (attribute.name == L"width") {
590             m_width = ParseSizeAttributeValue(attribute.value);
591         } else if (attribute.name == L"height") {
592             m_height = ParseSizeAttributeValue(attribute.value);
593         }
594     }
595
596     virtual void Accept(const Text& /*text*/)
597     {
598         ThrowMsg(Exception::ParseError, "Icon element must be empty");
599     }
600
601     virtual void Verify()
602     {
603         if (m_src.IsNull()) {
604             LogWarning("src attribute of icon element is mandatory - ignoring");
605             return;
606         }
607
608         Try
609         {
610             ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
611             icon.width = m_width;
612             icon.height = m_height;
613
614             ConfigParserData::IconsList::iterator it = std::find(
615                     m_data.iconsList.begin(), m_data.iconsList.end(), icon);
616             if (it == m_data.iconsList.end()) {
617                 m_data.iconsList.push_front(icon);
618             }
619         }
620         Catch(BadSrcError)
621         {
622             LogWarning("src attribute is invalid: " << m_src);
623         }
624     }
625
626   private:
627     ConfigParserData& m_data;
628     DPL::OptionalString m_src;
629     DPL::OptionalInt m_width;
630     DPL::OptionalInt m_height;
631
632     static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
633     {
634         DPL::OptionalString normalizedValue = value;
635         NormalizeString(normalizedValue);
636         if (!(*normalizedValue).empty()) {
637             char* reterr = NULL;
638             errno = 0;
639             long int valueInt =
640                 strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
641             if (errno != 0 ||
642                 std::string(reterr) == DPL::ToUTF8String(value) ||
643                 valueInt <= 0)
644             {
645                 return DPL::OptionalInt::Null;
646             } else {
647                 return valueInt;
648             }
649         }
650         return DPL::OptionalInt::Null;
651     }
652
653     /**
654      * @brief delocalizePath removes locales folder from relative path if
655      * neccessary
656      * @param source source string
657      *
658      * @throw BadSrcError if string is bad value of src attribute
659      *
660      * @return corrected string
661      */
662     static DPL::String delocalizeSrcPath(const DPL::String & source)
663     {
664         static const DPL::String localeFolder(L"locales/");
665         static const int index = localeFolder.size();
666
667         DPL::String result = source;
668
669         if (source.substr(0, index) == localeFolder) {
670             size_t pos = result.find_first_of('/', index);
671             if (pos != std::string::npos && pos + 1 < source.size()) {
672                 result = result.substr(pos + 1, source.size());
673             } else {
674                 Throw(BadSrcError);
675             }
676         }
677         return result;
678     }
679 };
680
681 class ContentParser : public ElementParser
682 {
683   public:
684     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
685                                         const DPL::String& /*name*/)
686     {
687         return &IgnoringParser::Create; //ignore unknown according to w3c
688     }
689
690     ContentParser(ConfigParserData& data) :
691         ElementParser(),
692         m_data(data)
693     {}
694
695     virtual void Accept(const Element& element)
696     {
697         m_namespace = element.ns;
698     }
699
700     virtual void Accept(const Text& /*text*/)
701     {}
702
703     virtual void Accept(const XmlAttribute& attribute)
704     {
705         DPL::String value = attribute.value;
706         NormalizeString(value);
707
708         if (attribute.name == L"src") {
709             m_src = value;
710         } else if (attribute.name == L"type") {
711             m_type = value;
712             MimeTypeUtils::MimeAttributes mimeAttributes =
713                 MimeTypeUtils::getMimeAttributes(value);
714             if ((mimeAttributes.count(L"charset") > 0) && m_encoding.IsNull())
715             {
716                 m_encoding = mimeAttributes[L"charset"];
717             }
718         } else if (attribute.name == L"encoding") {
719             if (!value.empty()) {
720                 m_encoding = value;
721             }
722         }
723     }
724
725     virtual void Verify()
726     {
727         if(!!m_data.startFileEncountered)
728         {
729             if(m_data.startFileNamespace == m_namespace
730                 || m_namespace != ConfigurationNamespace::TizenWebAppNamespaceName)
731             {
732                 return;
733             }
734             //else continue -> if previous item was not in tizen namespace
735         }
736
737         m_data.startFileEncountered = true;
738         m_data.startFileNamespace = m_namespace;
739
740         //we're consciously setting startFile even if m_src is null or invalid.
741         //WidgetConfigurationManager will deal with this.
742         m_data.startFile = m_src;
743
744         if (!!m_src) {
745             m_data.startFileContentType = m_type;
746             if (!!m_encoding) {
747                 m_data.startFileEncoding = m_encoding;
748             } else {
749                 m_data.startFileEncoding = L"UTF-8";
750             }
751         }
752     }
753
754   private:
755     DPL::OptionalString m_src;
756     DPL::OptionalString m_type;
757     DPL::OptionalString m_encoding;
758     ConfigParserData& m_data;
759     DPL::String m_namespace;
760 };
761
762 class PreferenceParser : public ElementParser
763 {
764   public:
765     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
766                                         const DPL::String& /*name*/)
767     {
768         return &IgnoringParser::Create; //ignore unknown according to w3c
769     }
770
771     virtual void Accept(const XmlAttribute& attribute)
772     {
773         if (attribute.name == L"name") {
774             m_name = attribute.value;
775         } else if (attribute.name == L"value") {
776             m_value = attribute.value;
777         } else if (attribute.name == L"readonly") {
778             if (attribute.value == L"true") {
779                 m_required = true;
780             } else {
781                 m_required = false;
782             }
783         }
784     }
785
786     virtual void Accept(const Element& /*element*/)
787     {}
788
789     virtual void Accept(const Text& /*text*/)
790     {
791         ThrowMsg(Exception::ParseError, "param element must be empty");
792     }
793
794     virtual void Verify()
795     {
796         if (m_name.IsNull()) {
797             LogWarning("preference element must have name attribute");
798             return;
799         }
800         NormalizeString(m_name);
801         NormalizeString(m_value);
802         ConfigParserData::Preference preference(*m_name, m_required);
803         preference.value = m_value;
804         if (m_data.preferencesList.find(preference) ==
805             m_data.preferencesList.end())
806         {
807             m_data.preferencesList.insert(preference);
808         }
809     }
810
811     PreferenceParser(ConfigParserData& data) :
812         ElementParser(),
813         m_required(false),
814         m_data(data)
815     {}
816
817   private:
818     DPL::OptionalString m_name;
819     DPL::OptionalString m_value;
820     bool m_required;
821     ConfigParserData& m_data;
822 };
823
824 class SettingParser : public ElementParser
825 {
826   public:
827     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
828                                         const DPL::String& /*name*/)
829     {
830         return &IgnoringParser::Create; //ignore unknown according to w3c
831     }
832
833     virtual void Accept(const Text& /*text*/)
834     {}
835
836     virtual void Accept(const Element& /*element*/)
837     {}
838
839     virtual void Accept(const XmlAttribute& attribute)
840     {
841         m_setting.m_name = attribute.name;
842         m_setting.m_value = attribute.value;
843         m_data.settingsList.insert(m_setting);
844     }
845
846     virtual void Verify()
847     {}
848
849     SettingParser(ConfigParserData& data) :
850         ElementParser(),
851         m_data(data),
852         m_setting(L"", L"")
853     {}
854
855   private:
856     ConfigParserData& m_data;
857     ConfigParserData::Setting m_setting;
858 };
859
860 class AppControlParser : public ElementParser
861 {
862   public:
863     struct SourceParser : public ElementParser
864     {
865       public:
866         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
867                                             const DPL::String& /*name*/)
868         {
869             return &IgnoringParser::Create; //ignore unknown according to w3c
870         }
871
872         virtual void Accept(const Text& /*text*/)
873         {}
874
875         virtual void Accept(const Element& /*element*/)
876         {}
877
878         virtual void Accept(const XmlAttribute& attribute)
879         {
880             if (attribute.name == L"name") {
881                 if (attribute.value.size() > 0) {
882                     m_value = attribute.value;
883                     NormalizeString(m_value);
884                 }
885             }
886         }
887
888         virtual void Verify()
889         {
890             if (m_value.IsNull() || *m_value == L"") {
891                 return;
892             }
893
894             m_data.m_src = *m_value;
895         }
896
897         SourceParser(ConfigParserData::AppControlInfo& data) :
898             ElementParser(),
899             m_properNamespace(false),
900             m_data(data)
901         {}
902
903       private:
904         bool m_properNamespace;
905         DPL::OptionalString m_value;
906         ConfigParserData::AppControlInfo& m_data;
907     };
908
909     struct OperationParser : public ElementParser
910     {
911       public:
912         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
913                                             const DPL::String& /*name*/)
914         {
915             return &IgnoringParser::Create; //ignore unknown according to w3c
916         }
917
918         virtual void Accept(const Text& /*text*/)
919         {}
920
921         virtual void Accept(const Element& /*element*/)
922         {}
923
924         virtual void Accept(const XmlAttribute& attribute)
925         {
926             if (attribute.name == L"name") {
927                 if (attribute.value.size() > 0) {
928                     m_value = attribute.value;
929                     NormalizeString(m_value);
930                 }
931             }
932         }
933
934         virtual void Verify()
935         {
936             if (m_value.IsNull() || *m_value == L"") {
937                 return;
938             }
939
940             m_data.m_operation = *m_value;
941         }
942
943         OperationParser(ConfigParserData::AppControlInfo& data) :
944             ElementParser(),
945             m_properNamespace(false),
946             m_data(data)
947         {}
948
949       private:
950         bool m_properNamespace;
951         DPL::OptionalString m_value;
952         ConfigParserData::AppControlInfo& m_data;
953     };
954
955     struct UriParser : public ElementParser
956     {
957       public:
958         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
959                                             const DPL::String& /*name*/)
960         {
961             return &IgnoringParser::Create; //ignore unknown according to w3c
962         }
963
964         virtual void Accept(const Text& /*text*/)
965         {}
966
967         virtual void Accept(const Element& /*element*/)
968         {}
969
970         virtual void Accept(const XmlAttribute& attribute)
971         {
972             if (attribute.name == L"name") {
973                 if (attribute.value.size() > 0) {
974                     m_value = attribute.value;
975                     NormalizeString(m_value);
976                 }
977             }
978         }
979
980         virtual void Verify()
981         {
982             // exception
983             DPL::String ignoreUri(L"file");
984
985             if (!m_value.IsNull() && *m_value == ignoreUri)
986             {
987                 LogInfo("exception : '" << *m_value << "' scheme will be ignored.");
988                 m_value = DPL::OptionalString::Null;
989             }
990
991             if (m_value.IsNull() || *m_value == L"") {
992                 return;
993             }
994
995             DPL::String wildString(L"*/*");
996             if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
997                 && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
998             {
999                 m_data.m_uriList.insert(*m_value);
1000             } else {
1001                 LogDebug("Ignoring uri with name" <<
1002                          DPL::ToUTF8String(*m_value));
1003             }
1004         }
1005
1006         UriParser(ConfigParserData::AppControlInfo& data) :
1007             ElementParser(),
1008             m_properNamespace(false),
1009             m_data(data)
1010         {}
1011
1012       private:
1013         bool m_properNamespace;
1014         DPL::OptionalString m_value;
1015         ConfigParserData::AppControlInfo& m_data;
1016     };
1017
1018     struct MimeParser : public ElementParser
1019     {
1020       public:
1021         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1022                                             const DPL::String& /*name*/)
1023         {
1024             return &IgnoringParser::Create; //ignore unknown according to w3c
1025         }
1026
1027         virtual void Accept(const Text& /*text*/)
1028         {}
1029
1030         virtual void Accept(const Element& /*element*/)
1031         {}
1032
1033         virtual void Accept(const XmlAttribute& attribute)
1034         {
1035             if (attribute.name == L"name") {
1036                 if (attribute.value.size() > 0) {
1037                     m_value = attribute.value;
1038                     NormalizeString(m_value);
1039                 }
1040             }
1041         }
1042
1043         virtual void Verify()
1044         {
1045             if (m_value.IsNull() || *m_value == L"") {
1046                 return;
1047             }
1048
1049             DPL::String wildString(L"*/*");
1050             if ((m_data.m_mimeList.find(wildString) ==
1051                  m_data.m_mimeList.end())
1052                 && (m_data.m_mimeList.find(*m_value) ==
1053                     m_data.m_mimeList.end()))
1054             {
1055                 m_data.m_mimeList.insert(*m_value);
1056             } else {
1057                 LogDebug("Ignoring mime with name" <<
1058                          DPL::ToUTF8String(*m_value));
1059             }
1060         }
1061
1062         MimeParser(ConfigParserData::AppControlInfo& data) :
1063             ElementParser(),
1064             m_properNamespace(false),
1065             m_data(data)
1066         {}
1067
1068       private:
1069         bool m_properNamespace;
1070         DPL::OptionalString m_value;
1071         ConfigParserData::AppControlInfo& m_data;
1072     };
1073
1074     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1075                                         const DPL::String& name)
1076     {
1077         if (name == L"src") {
1078             return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1079         } else if (name == L"operation") {
1080             return DPL::MakeDelegate(this,
1081                                      &AppControlParser::OnOperationElement);
1082         } else if (name == L"uri") {
1083             return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1084         } else if (name == L"mime") {
1085             return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1086         } else {
1087             return &IgnoringParser::Create; //ignore unknown according to w3c
1088         }
1089     }
1090
1091     virtual void Accept(const XmlAttribute& /*attribute*/)
1092     {}
1093
1094     virtual void Accept(const Element& element)
1095     {
1096         LogWarning("namespace for app service = " << element.ns);
1097         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1098             ThrowMsg(Exception::ParseError,
1099                      "Wrong xml namespace for widget element");
1100         }
1101     }
1102
1103     virtual void Accept(const Text& /*text*/)
1104     {
1105         ThrowMsg(Exception::ParseError, "param element must be empty");
1106     }
1107
1108     virtual void Verify()
1109     {
1110         if (m_appControl.m_src == L"") {
1111             ThrowMsg(Exception::ParseError, "service element must have src element");
1112         }
1113
1114         if (m_appControl.m_operation == L"") {
1115             ThrowMsg(Exception::ParseError, "service element must have operation element");
1116         }
1117
1118         m_data.appControlList.push_back(m_appControl);
1119     }
1120
1121     ElementParserPtr OnSourceElement()
1122     {
1123         return ElementParserPtr(new SourceParser(m_appControl));
1124     }
1125
1126     ElementParserPtr OnOperationElement()
1127     {
1128         return ElementParserPtr(new OperationParser(m_appControl));
1129     }
1130
1131     ElementParserPtr OnUriElement()
1132     {
1133         return ElementParserPtr(new UriParser(m_appControl));
1134     }
1135
1136     ElementParserPtr OnMimeElement()
1137     {
1138         return ElementParserPtr(new MimeParser(m_appControl));
1139     }
1140
1141     AppControlParser(ConfigParserData& data) :
1142         ElementParser(),
1143         m_data(data),
1144         m_appControl(L"")
1145     {}
1146
1147   private:
1148     ConfigParserData& m_data;
1149     ConfigParserData::AppControlInfo m_appControl;
1150 };
1151
1152 class ApplicationParser : public ElementParser
1153 {
1154   public:
1155     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1156                                         const DPL::String& /*name*/)
1157     {
1158         return &IgnoringParser::Create; //ignore unknown according to w3c
1159     }
1160
1161     virtual void Accept(const Text& /*text*/)
1162     {
1163         if (m_properNamespace) {
1164             ThrowMsg(Exception::ParseError, "application element must be empty");
1165         }
1166     }
1167
1168     virtual void Accept(const Element& element)
1169     {
1170         if (element.ns ==
1171             ConfigurationNamespace::TizenWebAppNamespaceName)
1172         {
1173             m_properNamespace = true;
1174         }
1175     }
1176
1177     virtual void Accept(const XmlAttribute& attribute)
1178     {
1179         if (m_properNamespace) {
1180             if (attribute.name == L"id") {
1181                 m_id = attribute.value;
1182                 NormalizeAndTrimSpaceString(m_id);
1183             } else if (attribute.name == L"package") {
1184                 m_package = attribute.value;
1185             } else if (attribute.name == L"required_version") {
1186                 m_version = attribute.value;
1187                 NormalizeString(m_version);
1188             } else {
1189                 ThrowMsg(Exception::ParseError,
1190                          "unknown attribute '" +
1191                          DPL::ToUTF8String(attribute.name) +
1192                          "' in application element");
1193             }
1194         }
1195     }
1196
1197     virtual void Verify()
1198     {
1199         VerifyIdAndPackage();
1200         VerifyVersion();
1201     }
1202
1203     ApplicationParser(ConfigParserData& data) :
1204         ElementParser(),
1205         m_data(data),
1206         m_id(DPL::OptionalString::Null),
1207         m_version(DPL::OptionalString::Null),
1208         m_properNamespace(false)
1209     {}
1210
1211     static const char* const REGEXP_ID;
1212
1213   private:
1214     void VerifyIdAndPackage()
1215     {
1216         if (!m_package)
1217         {
1218             ThrowMsg(Exception::ParseError,
1219                      "application element must have package attribute");
1220         }
1221         else
1222         {
1223             pcrecpp::RE re(REGEXP_PACKAGE);
1224             if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
1225             {
1226                 ThrowMsg(Exception::ParseError,
1227                          "invalid format of package attribute");
1228             }
1229         }
1230
1231         if (!m_id) {
1232             ThrowMsg(Exception::ParseError,
1233                      "application element must have id attribute");
1234         }
1235         else
1236         {
1237             std::string package;
1238             pcrecpp::RE re(REGEXP_ID);
1239             if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
1240             {
1241                 ThrowMsg(Exception::ParseError,
1242                          "invalid format of id attribute");
1243             }
1244             if (package != DPL::ToUTF8String(*m_package))
1245             {
1246                 ThrowMsg(Exception::ParseError,
1247                          "invalid package prefix in id attribute");
1248             }
1249         }
1250
1251         m_data.tizenAppId = m_id;
1252         m_data.tizenPkgId = m_package;
1253     }
1254
1255     void VerifyVersion()
1256     {
1257         if (!m_version)
1258         {
1259             ThrowMsg(Exception::ParseError,
1260                      "application element must have required_version attribute");
1261         }
1262         else
1263         {
1264             pcrecpp::RE re(REGEXP_VERSION);
1265             if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
1266             {
1267                 ThrowMsg(Exception::ParseError,
1268                          "invalid format of version attribute");
1269             }
1270         }
1271
1272         m_data.tizenMinVersionRequired = m_version;
1273     }
1274
1275     static const char* const REGEXP_PACKAGE;
1276     static const char* const REGEXP_VERSION;
1277
1278     ConfigParserData& m_data;
1279     DPL::OptionalString m_id;
1280     DPL::OptionalString m_package;
1281     DPL::OptionalString m_version;
1282     bool m_properNamespace;
1283 };
1284
1285 const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
1286 const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
1287 const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)?";
1288
1289 class SplashParser : public ElementParser
1290 {
1291   public:
1292     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1293                                         const DPL::String& /*name*/)
1294     {
1295         return &IgnoringParser::Create; //ignore unknown according to w3c
1296     }
1297
1298     virtual void Accept(const XmlAttribute& attribute)
1299     {
1300         if (m_properNamespace)
1301         {
1302             if (attribute.name == L"src") {
1303                 if (attribute.value.size() > 0) {
1304                     m_src = attribute.value;
1305                 }
1306             }
1307         }
1308     }
1309
1310     virtual void Accept(const Element& element)
1311     {
1312         if (element.ns ==
1313             ConfigurationNamespace::TizenWebAppNamespaceName)
1314         {
1315             m_properNamespace = true;
1316         }
1317     }
1318
1319     virtual void Accept(const Text& /*text*/)
1320     {}
1321
1322     virtual void Verify()
1323     {
1324         if (m_src.IsNull())
1325         {
1326             LogWarning("src attribute of splash element is mandatory - ignoring");
1327             return;
1328         }
1329
1330         m_data.splashImgSrc = m_src;
1331     }
1332
1333     SplashParser(ConfigParserData& data) :
1334         ElementParser(),
1335         m_data(data),
1336         m_properNamespace(false)
1337     {}
1338
1339   private:
1340     DPL::OptionalString m_src;
1341     ConfigParserData& m_data;
1342     bool m_properNamespace;
1343 };
1344
1345 class BackgroundParser : public ElementParser
1346 {
1347   public:
1348     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1349                                         const DPL::String& /*name*/)
1350     {
1351         return &IgnoringParser::Create; //ignore unknown according to w3c
1352     }
1353
1354     virtual void Accept(const XmlAttribute& attribute)
1355     {
1356         if (attribute.name == L"src") {
1357             if (attribute.value.size() > 0) {
1358                 m_src = attribute.value;
1359             }
1360         }
1361     }
1362
1363     virtual void Accept(const Element& /*element*/)
1364     {}
1365
1366     virtual void Accept(const Text& /*text*/)
1367     {}
1368
1369     virtual void Verify()
1370     {
1371         if (m_src.IsNull()) {
1372             LogWarning(
1373                 "src attribute of background element is mandatory - ignoring");
1374             return;
1375         }
1376
1377         m_data.backgroundPage = m_src;
1378     }
1379
1380     explicit BackgroundParser(ConfigParserData& data) :
1381         m_data(data)
1382     {}
1383
1384   private:
1385     DPL::OptionalString m_src;
1386     ConfigParserData& m_data;
1387 };
1388
1389 class PrivilegeParser : public ElementParser
1390 {
1391   public:
1392     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1393                                         const DPL::String& /*name*/)
1394     {
1395         return &IgnoringParser::Create; //ignore unknown according to w3c
1396     }
1397
1398     virtual void Accept(const Text& /*text*/)
1399     {}
1400
1401     virtual void Accept(const Element& element)
1402     {
1403         if (element.ns ==
1404             ConfigurationNamespace::TizenWebAppNamespaceName)
1405         {
1406             m_properNamespace = true;
1407         }
1408         LogDebug("element");
1409     }
1410
1411     virtual void Accept(const XmlAttribute& attribute)
1412     {
1413         if (m_properNamespace) {
1414             if (attribute.name == L"name") {
1415                 m_feature.name = attribute.value;
1416                 m_privilege.name = attribute.value;
1417             }
1418         }
1419     }
1420
1421     virtual void Verify()
1422     {
1423         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1424
1425         if (m_feature.name != L"") {
1426             if (iri.Validate()) {
1427                 if (m_data.featuresList.find(m_feature) ==
1428                     m_data.featuresList.end())
1429                 {
1430                     m_data.featuresList.insert(m_feature);
1431                 } else {
1432                     LogDebug("Ignoring feature with name" <<
1433                         DPL::ToUTF8String(m_feature.name));
1434                 }
1435             }
1436         }
1437
1438         LibIri::Wrapper iriPrivilege(
1439             DPL::ToUTF8String(m_privilege.name).c_str());
1440
1441         if (m_privilege.name != L"") {
1442             if (iriPrivilege.Validate()) {
1443                 if (m_data.privilegeList.find(m_privilege) ==
1444                     m_data.privilegeList.end())
1445                 {
1446                     m_data.privilegeList.insert(m_privilege);
1447                 } else {
1448                     LogDebug("Ignoring privilege with name" <<
1449                              DPL::ToUTF8String(m_privilege.name));
1450                 }
1451             }
1452         }
1453     }
1454
1455     PrivilegeParser(ConfigParserData& data) :
1456         ElementParser(),
1457         m_data(data),
1458         m_feature(L""),
1459         m_privilege(L""),
1460         m_properNamespace(false)
1461     {}
1462
1463   private:
1464     ConfigParserData& m_data;
1465     ConfigParserData::Feature m_feature;
1466     ConfigParserData::Privilege m_privilege;
1467     bool m_properNamespace;
1468 };
1469
1470 class CategoryParser : public ElementParser
1471 {
1472   public:
1473     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1474                                         const DPL::String& /*name*/)
1475     {
1476         return &IgnoringParser::Create; //ignore unknown according to w3c
1477     }
1478
1479     virtual void Accept(const XmlAttribute& attribute)
1480     {
1481         if (attribute.name == L"name") {
1482             if (attribute.value.size() > 0) {
1483                 m_name = attribute.value;
1484             }
1485         }
1486     }
1487
1488     virtual void Accept(const Element& /*element*/)
1489     {}
1490
1491     virtual void Accept(const Text& /*text*/)
1492     {}
1493
1494     virtual void Verify()
1495     {
1496         if (m_name.IsNull()) {
1497             LogWarning(
1498                 "name attribute of category element is mandatory - ignoring");
1499             return;
1500         }
1501
1502         if (m_data.categoryList.find(*m_name) ==
1503             m_data.categoryList.end())
1504         {
1505             m_data.categoryList.insert(*m_name);
1506         }
1507     }
1508
1509     explicit CategoryParser(ConfigParserData& data) :
1510         m_data(data)
1511     {}
1512
1513   private:
1514     DPL::OptionalString m_name;
1515     ConfigParserData& m_data;
1516 };
1517
1518 class AppWidgetParser : public ElementParser
1519 {
1520   public:
1521
1522     struct BoxLabelParser : public ElementParser
1523     {
1524         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1525                                             const DPL::String& /*name*/)
1526         {
1527             return &IgnoringParser::Create; //ignore unknown according to w3c
1528         }
1529
1530         virtual void Accept(const XmlAttribute& attribute)
1531         {
1532             if (m_properNamespace) {
1533                  m_lang = attribute.lang;
1534             }
1535         }
1536         virtual void Accept(const Element& element)
1537         {
1538             if (element.ns ==
1539                 ConfigurationNamespace::TizenWebAppNamespaceName)
1540             {
1541                 m_properNamespace = true;
1542             }
1543         }
1544
1545         virtual void Accept(const Text& text)
1546         {
1547             if (m_properNamespace) {
1548                 m_label = text.value;
1549             }
1550         }
1551
1552         virtual void Verify()
1553         {
1554             std::pair<DPL::String, DPL::String> boxLabel;
1555             if (m_label.empty()) {
1556                 LogWarning("box-label element is empty");
1557                 boxLabel.first = DPL::FromUTF8String("");
1558                 boxLabel.second = DPL::FromUTF8String("");
1559                 m_data.m_label.push_back(boxLabel);
1560             }
1561             else {
1562                 boxLabel.first = m_lang;
1563                 boxLabel.second = m_label;
1564                 m_data.m_label.push_back(boxLabel);
1565             }
1566         }
1567
1568         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1569             ElementParser(),
1570             m_properNamespace(false),
1571             m_data(data)
1572         {}
1573
1574       private:
1575         DPL::String m_lang;
1576         DPL::String m_label;
1577         bool m_properNamespace;
1578         ConfigParserData::LiveboxInfo& m_data;
1579     };
1580
1581     struct BoxIconParser : public ElementParser
1582     {
1583         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1584                                             const DPL::String& /*name*/)
1585         {
1586             return &IgnoringParser::Create; //ignore unknown according to w3c
1587         }
1588
1589         virtual void Accept(const XmlAttribute& attribute)
1590         {
1591             if (m_properNamespace) {
1592                 if (attribute.name == L"src") {
1593                     m_icon = attribute.value;
1594                 }
1595             }
1596         }
1597
1598         virtual void Accept(const Element& element)
1599         {
1600             if (element.ns ==
1601                 ConfigurationNamespace::TizenWebAppNamespaceName)
1602             {
1603                 m_properNamespace = true;
1604             }
1605         }
1606
1607         virtual void Accept(const Text& /*text*/)
1608         {}
1609
1610         virtual void Verify()
1611         {
1612             if (m_icon.empty()) {
1613                 ThrowMsg(Exception::ParseError,
1614                     "src attribute of box-icon element is mandatory - ignoring");
1615             }
1616             m_data.m_icon = m_icon;
1617         }
1618
1619         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1620             ElementParser(),
1621             m_properNamespace(false),
1622             m_data(data)
1623         {}
1624
1625       private:
1626         DPL::String m_icon;
1627         bool m_properNamespace;
1628         ConfigParserData::LiveboxInfo& m_data;
1629     };
1630
1631     struct BoxContentParser : public ElementParser
1632     {
1633         struct BoxSizeParser : public ElementParser
1634         {
1635             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1636                                                 const DPL::String& /*name*/)
1637             {
1638                 return &IgnoringParser::Create; //ignore unknown according to w3c
1639             }
1640
1641             virtual void Accept(const XmlAttribute& attribute)
1642             {
1643                 if (m_properNamespace) {
1644                     if (attribute.name == L"preview") {
1645                         m_preview = attribute.value;
1646                     }
1647                     if (attribute.name == L"use-decoration") {
1648                         m_useDecoration = attribute.value;
1649                     }
1650                 }
1651             }
1652
1653             virtual void Accept(const Element& element)
1654             {
1655                 if (element.ns ==
1656                     ConfigurationNamespace::TizenWebAppNamespaceName)
1657                 {
1658                     m_properNamespace = true;
1659                 }
1660             }
1661
1662             virtual void Accept(const Text& text)
1663             {
1664                 if (m_properNamespace) {
1665                     m_size = text.value;
1666                 }
1667             }
1668
1669             virtual void Verify()
1670             {
1671                 if(m_size.empty()) {
1672                     ThrowMsg(Exception::ParseError,
1673                         "size is mandatory - ignoring");
1674                 }
1675
1676                 ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
1677                 boxSizeInfo.m_size = m_size;
1678                 boxSizeInfo.m_preview = m_preview;
1679                 boxSizeInfo.m_useDecoration = m_useDecoration;
1680                 m_data.m_boxSize.push_back(boxSizeInfo);
1681             }
1682
1683             explicit BoxSizeParser(
1684                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1685                 ElementParser(),
1686                 m_properNamespace(false),
1687                 m_data(data)
1688             {}
1689
1690           private:
1691             DPL::String m_size;
1692             DPL::String m_preview;
1693             DPL::String m_useDecoration;
1694             bool m_properNamespace;
1695             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1696         };
1697
1698         struct PdParser : public ElementParser
1699         {
1700             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1701                                                 const DPL::String& /*name*/)
1702             {
1703                 return &IgnoringParser::Create; //ignore unknown according to w3c
1704             }
1705
1706             virtual void Accept(const XmlAttribute& attribute)
1707             {
1708                 if (m_properNamespace) {
1709                     if (attribute.name == L"src") {
1710                         m_src = attribute.value;
1711                     } else if (attribute.name == L"width") {
1712                         m_width = attribute.value;
1713                     } else if (attribute.name == L"height") {
1714                         m_height = attribute.value;
1715                     } else if (attribute.name == L"fast-open") {
1716                         m_fastOpen= attribute.value;
1717                     }
1718                 }
1719             }
1720
1721             virtual void Accept(const Element& element)
1722             {
1723                 if (element.ns ==
1724                     ConfigurationNamespace::TizenWebAppNamespaceName)
1725                 {
1726                     m_properNamespace = true;
1727                 }
1728             }
1729
1730             virtual void Accept(const Text& /*text*/)
1731             {}
1732
1733             virtual void Verify()
1734             {
1735                 if (m_src.empty()) {
1736                     ThrowMsg(Exception::ParseError,
1737                         "src attribute of pd element is mandatory - ignoring");
1738                 }
1739
1740                 if (m_width.empty()) {
1741                     ThrowMsg(Exception::ParseError,
1742                         "width attribute of pd element is mandatory - ignoring");
1743                 }
1744
1745                 if (m_height.empty()) {
1746                     ThrowMsg(Exception::ParseError,
1747                         "height attribute of pd element is mandatory - ignoring");
1748                 }
1749
1750                 if (ConvertToInt(m_width).IsNull()) {
1751                     ThrowMsg(Exception::ParseError,
1752                         "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
1753                 }
1754
1755
1756                 DPL::OptionalInt height = ConvertToInt(m_height);
1757
1758                 if (height.IsNull()) {
1759                     ThrowMsg(Exception::ParseError,
1760                         "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
1761                 }
1762
1763                 if (*height < 1) {
1764                     m_height = L"1";
1765                     LogDebug("height attribute of pd element shouldn't be less than 1. Changed to 1 from " << *height);
1766                 } else if (*height > 380){
1767                     m_height = L"380";
1768                     LogDebug("height attribute of pd element shouldn't be greater than 380. Changed to 380 from " << *height);
1769                 }
1770
1771                 m_data.m_pdSrc = m_src;
1772                 m_data.m_pdWidth = m_width;
1773                 m_data.m_pdHeight = m_height;
1774                 m_data.m_pdFastOpen = m_fastOpen;
1775             }
1776
1777             explicit PdParser(
1778                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1779                 ElementParser(),
1780                 m_properNamespace(false),
1781                 m_data(data)
1782             {}
1783
1784           private:
1785             DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
1786             {
1787                 char * endptr;
1788                 std::string tempStr = DPL::ToUTF8String(intAsString);
1789                 const char * intAsString_c = tempStr.c_str();
1790                 errno = 0;
1791                 long int intAsString_i = strtol(intAsString_c, &endptr, 10);
1792
1793                 if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
1794                         || intAsString_i > INT_MAX || intAsString_i < INT_MIN
1795                         || *endptr != '\0') {
1796                     return DPL::OptionalInt::Null;
1797                 }
1798
1799                 return static_cast<int>(intAsString_i);
1800             }
1801
1802             DPL::String m_src;
1803             DPL::String m_width;
1804             DPL::String m_height;
1805             DPL::String m_fastOpen;
1806
1807             bool m_properNamespace;
1808             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1809         };
1810
1811         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1812                                             const DPL::String& name)
1813         {
1814             if (name == L"box-size") {
1815                 return DPL::MakeDelegate(
1816                            this,
1817                            &AppWidgetParser::BoxContentParser::
1818                                OnBoxSizeElement);
1819             } else if (name == L"pd") {
1820                 return DPL::MakeDelegate(
1821                            this,
1822                            &AppWidgetParser::BoxContentParser::
1823                                OnPdElement);
1824             } else {
1825                 ThrowMsg(Exception::ParseError,
1826                          "No element parser for name: " << name);
1827             }
1828         }
1829
1830         virtual void Accept(const XmlAttribute& attribute)
1831         {
1832             if (m_properNamespace) {
1833                 if (attribute.name == L"src") {
1834                     m_box.m_boxSrc = attribute.value;
1835                 }
1836                 if (attribute.name == L"mouse-event") {
1837                     m_box.m_boxMouseEvent = attribute.value;
1838                 }
1839                 if (attribute.name == L"touch-effect") {
1840                     m_box.m_boxTouchEffect = attribute.value;
1841                 }
1842             }
1843         }
1844
1845         virtual void Accept(const Element& element)
1846         {
1847             if (element.ns ==
1848                 ConfigurationNamespace::TizenWebAppNamespaceName)
1849             {
1850                 m_properNamespace = true;
1851             }
1852         }
1853
1854         virtual void Accept(const Text& /*text*/)
1855         {}
1856
1857         virtual void Verify()
1858         {
1859             if (m_box.m_boxSrc.empty()) {
1860                 ThrowMsg(Exception::ParseError,
1861                     "src attribute of box-content element is mandatory - ignoring");
1862             }
1863
1864             if (!m_box.m_boxMouseEvent.empty() &&
1865                     CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent))
1866             {
1867                 ThrowMsg(Exception::ParseError,
1868                     "mouse-event attribute of box-content element should be true or false - ignoring");
1869             }
1870
1871             if (!m_box.m_boxTouchEffect.empty() &&
1872                     CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect))
1873             {
1874                 ThrowMsg(Exception::ParseError,
1875                     "touch-effect attribute of box-content element should be true or false - ignoring");
1876             }
1877
1878             if (m_box.m_boxMouseEvent.empty()) {
1879                 m_box.m_boxMouseEvent = L"false";
1880             }
1881
1882             if (m_box.m_boxTouchEffect.empty()) {
1883                 m_box.m_boxTouchEffect = L"true";
1884             }
1885
1886             if (m_box.m_boxSize.empty()) {
1887                 ThrowMsg(Exception::ParseError,
1888                     "box-size element of box-content element not found - ignoring");
1889             }
1890
1891             m_data.m_boxInfo = m_box;
1892         }
1893
1894         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1895             ElementParser(),
1896             m_properNamespace(false),
1897             m_data(data)
1898         {}
1899
1900         ElementParserPtr OnBoxSizeElement()
1901         {
1902             return ElementParserPtr(new BoxSizeParser(m_box));
1903         }
1904
1905         ElementParserPtr OnPdElement()
1906         {
1907             return ElementParserPtr(new PdParser(m_box));
1908         }
1909
1910       private:
1911         bool m_properNamespace;
1912         ConfigParserData::LiveboxInfo& m_data;
1913         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1914     };
1915
1916     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1917                                         const DPL::String& name)
1918     {
1919         if (name == L"box-label") {
1920             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
1921         } else if (name == L"box-icon") {
1922             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
1923         } else if (name == L"box-content") {
1924             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
1925         } else {
1926             return &IgnoringParser::Create; //ignore unknown according to w3c
1927         }
1928     }
1929
1930     virtual void Accept(const XmlAttribute& attribute)
1931     {
1932         if (m_properNamespace) {
1933             if (attribute.name == L"id") {
1934                 m_liveboxId = attribute.value;
1935             } else if (attribute.name == L"primary") {
1936                 m_primary = attribute.value;
1937             } else if (attribute.name == L"auto-launch") {
1938                 m_autoLaunch = attribute.value;
1939             } else if (attribute.name == L"update-period") {
1940                 m_updatePeriod = attribute.value;
1941             } else if (attribute.name == L"type") {
1942                 m_type = attribute.value;
1943             }
1944         }
1945     }
1946
1947     virtual void Accept(const Element& element)
1948     {
1949         if (element.ns ==
1950             ConfigurationNamespace::TizenWebAppNamespaceName)
1951         {
1952             m_properNamespace = true;
1953         }
1954     }
1955
1956     virtual void Accept(const Text& /*text*/)
1957     {}
1958
1959     virtual void Verify()
1960     {
1961         if (m_liveboxId.empty()) {
1962             ThrowMsg(Exception::ParseError,
1963                  "app-widget element must have id attribute");
1964         }
1965         else
1966         {
1967             pcrecpp::RE re(REGEXP_ID_STRING.c_str());
1968             if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
1969             {
1970                 ThrowMsg(Exception::ParseError,
1971                      "invalid format of app-widget id attribute");
1972             }
1973         }
1974
1975         if (m_primary.empty())
1976         {
1977             ThrowMsg(Exception::ParseError,
1978                  "app-widget element must have primary attribute");
1979         } else if (CheckIfNotTrueNorFalse(m_primary))
1980         {
1981             ThrowMsg(Exception::ParseError,
1982                 "auto-launch attribute of app-widget element should be true or false - ignoring");
1983         }
1984
1985         if (!m_autoLaunch.empty() &&
1986                 CheckIfNotTrueNorFalse(m_autoLaunch))
1987         {
1988             ThrowMsg(Exception::ParseError,
1989                 "auto-launch attribute of app-widget element should be true or false - ignoring");
1990         }
1991
1992         if (!m_updatePeriod.empty())
1993         {
1994             char * endptr;
1995             errno = 0;
1996             std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
1997
1998             //set standard locale to fix decimal point mark - '.'
1999             std::string currentLocale = setlocale(LC_NUMERIC, NULL);
2000             if (NULL == setlocale(LC_NUMERIC, "C"))
2001                 LogWarning("Failed to change locale to \"C\"");
2002             double updatePeriod = strtod(tempStr.c_str(), &endptr);
2003
2004             //go back to previous locale
2005             if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
2006                 LogWarning("Failed to set previous locale");
2007
2008             if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
2009                     || *endptr != '\0') {
2010                 ThrowMsg(Exception::ParseError,
2011                     "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
2012             } else if (updatePeriod < 1800.0) {
2013                 LogDebug("update-period attribute of app-widget element shouldn't be less than 1800.0 - changed to 1800 from value: " << m_updatePeriod);
2014                 m_updatePeriod = L"1800.0";
2015             }
2016         }
2017
2018         if (m_autoLaunch.empty()) {
2019             m_autoLaunch = L"false";
2020         }
2021
2022         if(m_livebox.m_label.empty()) {
2023             ThrowMsg(Exception::ParseError,
2024                 "box-label element of app-widget element not found - ignoring");
2025         }
2026
2027         if(!m_boxContentFound) {
2028             ThrowMsg(Exception::ParseError,
2029                 "box-content element of app-widget element not found - ignoring");
2030         }
2031
2032         m_livebox.m_liveboxId = m_liveboxId;
2033         m_livebox.m_primary = m_primary;
2034         m_livebox.m_autoLaunch = m_autoLaunch;
2035         m_livebox.m_updatePeriod = m_updatePeriod;
2036         m_livebox.m_type = m_type;
2037
2038         m_data.m_livebox.push_back(m_livebox);
2039     }
2040
2041     explicit AppWidgetParser(ConfigParserData& data) :
2042         ElementParser(),
2043         m_data(data),
2044         m_properNamespace(false),
2045         m_boxContentFound(false)
2046     {
2047         m_livebox = ConfigParserData::LiveboxInfo();
2048     }
2049
2050     ElementParserPtr OnBoxLabelElement()
2051     {
2052
2053         return ElementParserPtr(new BoxLabelParser(m_livebox));
2054     }
2055
2056     ElementParserPtr OnBoxIconElement()
2057     {
2058         return ElementParserPtr(new BoxIconParser(m_livebox));
2059     }
2060
2061     ElementParserPtr OnBoxContentElement()
2062     {
2063         m_boxContentFound = true;
2064         return ElementParserPtr(new BoxContentParser(m_livebox));
2065     }
2066
2067   private:
2068     static std::string REGEXP_ID_STRING;
2069     ConfigParserData& m_data;
2070     ConfigParserData::LiveboxInfo m_livebox;
2071     DPL::String m_liveboxId;
2072     DPL::String m_primary;
2073     DPL::String m_autoLaunch;
2074     DPL::String m_updatePeriod;
2075     DPL::String m_type;
2076     bool m_properNamespace;
2077     bool m_boxContentFound;
2078
2079     static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
2080     {
2081         return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
2082     }
2083 };
2084
2085 std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
2086
2087 class AllowNavigationParser : public ElementParser
2088 {
2089   public:
2090     AllowNavigationParser(ConfigParserData& data) :
2091       ElementParser(),
2092       m_data(data),
2093       m_properNamespace(false)
2094     {}
2095
2096     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2097                                         const DPL::String& /*name*/)
2098     {
2099         return &IgnoringParser::Create; //ignore unknown according to w3c
2100     }
2101
2102     virtual void Accept(const Element& element)
2103     {
2104         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2105             m_properNamespace = true;
2106         }
2107     }
2108
2109     virtual void Accept(const Text& text)
2110     {
2111         if (m_properNamespace) {
2112             m_origin = text.value;
2113         }
2114     }
2115
2116     virtual void Accept(const XmlAttribute& /*attribute*/)
2117     {
2118     }
2119
2120     virtual void Verify()
2121     {
2122         if (m_origin.IsNull()) {
2123             LogWarning("data is empty");
2124             return;
2125         }
2126
2127         char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
2128         char* ptr = strtok(data," ");
2129         while (ptr != NULL) {
2130             std::string origin = ptr;
2131             ptr = strtok(NULL," ");
2132             if(origin == "*") {
2133                 ConfigParserData::AllowNavigationInfo info(L"*", L"*");
2134                 m_data.allowNavigationInfoList.push_back(info);
2135                 continue;
2136             }
2137
2138             DPL::ScopedPtr<iri_t> iri(iri_parse(origin.c_str()));
2139             if (!iri->host || strlen(iri->host) == 0) {
2140                 // input origin should has schem and host
2141                 // in case of file scheme path is filled
2142                 // "http://"
2143                 LogWarning("input origin isn't verified");
2144                 continue;
2145             }
2146             DPL::String scheme = L"*";
2147             if (iri->scheme && strlen(iri->scheme) != 0) {
2148                 scheme = DPL::FromUTF8String(iri->scheme);
2149             }
2150             ConfigParserData::AllowNavigationInfo info(
2151                 scheme,
2152                 DPL::FromUTF8String(iri->host));
2153             m_data.allowNavigationInfoList.push_back(info);
2154         }
2155         free(data);
2156     }
2157
2158   private:
2159     DPL::OptionalString m_origin;
2160     ConfigParserData& m_data;
2161     bool m_properNamespace;
2162 };
2163
2164 class CspParser : public ElementParser
2165 {
2166   public:
2167     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2168                                         const DPL::String& /*name*/)
2169     {
2170         return &IgnoringParser::Create; //ignore unknown according to w3c
2171     }
2172
2173     CspParser(ConfigParserData& data) :
2174         ElementParser(),
2175         m_data(data),
2176         m_properNamespace(false)
2177     {}
2178
2179     virtual void Accept(const Element& element)
2180     {
2181         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2182             m_properNamespace = true;
2183         }
2184     }
2185
2186     virtual void Accept(const XmlAttribute& /*attribute*/)
2187     {}
2188
2189     virtual void Accept(const Text& text)
2190     {
2191         if (m_properNamespace) {
2192             m_policy = text.value;
2193         }
2194     }
2195
2196     virtual void Verify()
2197     {
2198         if (!m_policy.IsNull()) {
2199             m_data.cspPolicy = *m_policy;
2200         }
2201     }
2202
2203   private:
2204     ConfigParserData& m_data;
2205     bool m_properNamespace;
2206     DPL::OptionalString m_policy;
2207 };
2208
2209 class CspReportOnlyParser : public ElementParser
2210 {
2211   public:
2212     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2213                                         const DPL::String& /*name*/)
2214     {
2215         return &IgnoringParser::Create; //ignore unknown according to w3c
2216     }
2217
2218     CspReportOnlyParser(ConfigParserData& data) :
2219         ElementParser(),
2220         m_data(data),
2221         m_properNamespace(false)
2222     {}
2223
2224     virtual void Accept(const Element& element)
2225     {
2226         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2227             m_properNamespace = true;
2228         }
2229     }
2230
2231     virtual void Accept(const XmlAttribute& /*attribute*/)
2232     {}
2233
2234     virtual void Accept(const Text& text)
2235     {
2236         if (m_properNamespace) {
2237             m_policy = text.value;
2238         }
2239     }
2240
2241     virtual void Verify()
2242     {
2243         if (!m_policy.IsNull()) {
2244             m_data.cspPolicyReportOnly = *m_policy;
2245         }
2246     }
2247
2248   private:
2249     ConfigParserData& m_data;
2250     bool m_properNamespace;
2251     DPL::OptionalString m_policy;
2252 };
2253
2254 class AccountParser : public ElementParser
2255 {
2256   public:
2257     struct AccountProviderParser : public ElementParser
2258     {
2259       public:
2260
2261           struct IconParser : public ElementParser
2262         {
2263             public:
2264                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2265                         const DPL::String& /*name*/)
2266                 {
2267                     return &IgnoringParser::Create; //ignore unknown according to w3c
2268                 }
2269
2270                 virtual void Accept(const Text& text)
2271                 {
2272                     if (text.value == L"") {
2273                         return;
2274                     }
2275                     m_value = text.value;
2276                 }
2277
2278                 virtual void Accept(const Element& /*element*/)
2279                 {}
2280
2281                 virtual void Accept(const XmlAttribute& attribute)
2282                 {
2283                     if (attribute.name == L"section") {
2284                         if (attribute.value == L"account") {
2285                             m_type = ConfigParserData::IconSectionType::DefaultIcon;
2286                         } else if (attribute.value == L"account-small") {
2287                             m_type = ConfigParserData::IconSectionType::SmallIcon;
2288                         }
2289                     }
2290                 }
2291
2292                 virtual void Verify()
2293                 {
2294                     if (m_value.IsNull() || *m_value == L"") {
2295                         return;
2296                     }
2297
2298                     std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2299                     icon.first = m_type;
2300                     icon.second = *m_value;
2301
2302                     m_data.m_iconSet.insert(icon);
2303                 }
2304
2305                 IconParser(ConfigParserData::AccountProvider& data) :
2306                     ElementParser(),
2307                     m_properNamespace(false),
2308                     m_type(ConfigParserData::DefaultIcon),
2309                     m_data(data)
2310             {}
2311
2312             private:
2313                 bool m_properNamespace;
2314                 ConfigParserData::IconSectionType m_type;
2315                 ConfigParserData::AccountProvider& m_data;
2316                 DPL::OptionalString m_value;
2317         };
2318
2319           struct DisplayNameParser : public ElementParser
2320         {
2321             public:
2322                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2323                         const DPL::String& /*name*/)
2324                 {
2325                     return &IgnoringParser::Create; //ignore unknown according to w3c
2326                 }
2327
2328                 virtual void Accept(const Text& text)
2329                 {
2330                     if (text.value == L"") {
2331                         return;
2332                     }
2333                     m_value = text.value;
2334                 }
2335
2336                 virtual void Accept(const Element& element)
2337                 {
2338                     m_lang = element.lang;
2339                     m_value= L"";
2340                 }
2341
2342                 virtual void Accept(const XmlAttribute& /*attribute*/)
2343                 {}
2344
2345                 virtual void Verify()
2346                 {
2347                     if (m_value.IsNull() || *m_value == L"") {
2348                         return;
2349                     }
2350
2351                     std::pair<DPL::String, DPL::String> name;
2352                     name.first = *m_lang;
2353                     name.second = *m_value;
2354
2355                     m_data.m_displayNameSet.insert(name);
2356                 }
2357
2358                 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2359                     ElementParser(),
2360                     m_properNamespace(false),
2361                     m_data(data)
2362             {}
2363
2364             private:
2365                 bool m_properNamespace;
2366                 DPL::OptionalString m_lang;
2367                 DPL::OptionalString m_value;
2368                 ConfigParserData::AccountProvider& m_data;
2369         };
2370
2371           struct CapabilityParser : public ElementParser
2372         {
2373             public:
2374                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2375                         const DPL::String& /*name*/)
2376                 {
2377                     return &IgnoringParser::Create; //ignore unknown according to w3c
2378                 }
2379
2380                 virtual void Accept(const Text& text)
2381                 {
2382                     if (text.value == L"") {
2383                         return;
2384                     }
2385                     m_value = text.value;
2386                 }
2387
2388                 virtual void Accept(const Element& /*element*/)
2389                 {}
2390
2391                 virtual void Accept(const XmlAttribute& /*attribute*/)
2392                 {}
2393
2394                 virtual void Verify()
2395                 {
2396                     if (m_value.IsNull() || *m_value == L"") {
2397                         return;
2398                     }
2399                     m_data.m_capabilityList.push_back(*m_value);
2400                 }
2401
2402                 CapabilityParser(ConfigParserData::AccountProvider& data) :
2403                     ElementParser(),
2404                     m_properNamespace(false),
2405                     m_data(data)
2406             {}
2407
2408             private:
2409                 bool m_properNamespace;
2410                 DPL::OptionalString m_value;
2411                 ConfigParserData::AccountProvider& m_data;
2412         };
2413           virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2414                   const DPL::String& name)
2415           {
2416               if (name == L"icon") {
2417                   return DPL::MakeDelegate(this, &AccountProviderParser::OnIconElement);
2418               } else if (name == L"display-name") {
2419                   return DPL::MakeDelegate(this,
2420                           &AccountProviderParser::OnDisplayNameElement);
2421               } else if (name == L"capability") {
2422                   return DPL::MakeDelegate(this, &AccountProviderParser::OnCapabilityElement);
2423               } else {
2424                   return &IgnoringParser::Create; //ignore unknown according to w3c
2425               }
2426           }
2427
2428           virtual void Accept(const Text& /*text*/)
2429           {}
2430
2431           virtual void Accept(const Element& /*element*/)
2432           {}
2433
2434           virtual void Accept(const XmlAttribute& attribute)
2435           {
2436               if (attribute.name == L"multiple-accounts-support") {
2437                   if (attribute.value == L"true") {
2438                       m_multiSupport = true;
2439                   }
2440               }
2441           }
2442
2443           virtual void Verify()
2444           {
2445               m_data.m_multiAccountSupport = m_multiSupport;
2446           }
2447
2448           ElementParserPtr OnIconElement()
2449           {
2450               return ElementParserPtr(new IconParser(m_data));
2451           }
2452
2453           ElementParserPtr OnDisplayNameElement()
2454           {
2455               return ElementParserPtr(new DisplayNameParser(m_data));
2456           }
2457
2458           ElementParserPtr OnCapabilityElement()
2459           {
2460               return ElementParserPtr(new CapabilityParser(m_data));
2461           }
2462
2463           AccountProviderParser(ConfigParserData::AccountProvider& data) :
2464               ElementParser(),
2465               m_properNamespace(false),
2466               m_multiSupport(false),
2467               m_data(data)
2468         {}
2469
2470       private:
2471           bool m_properNamespace;
2472           bool m_multiSupport;
2473           ConfigParserData::AccountProvider& m_data;
2474     };
2475
2476     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2477             const DPL::String& name)
2478     {
2479         if (name == L"account-provider") {
2480             return DPL::MakeDelegate(this, &AccountParser::OnProviderElement);
2481         } else {
2482             return &IgnoringParser::Create; //ignore unknown according to w3c
2483         }
2484     }
2485
2486     virtual void Accept(const Element& element)
2487     {
2488         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2489             m_properNamespace = true;
2490         }
2491     }
2492
2493     virtual void Accept(const XmlAttribute& /*attribute*/)
2494     {}
2495
2496     virtual void Accept(const Text& /*text*/)
2497     {}
2498
2499     virtual void Verify()
2500     {}
2501
2502     ElementParserPtr OnProviderElement()
2503     {
2504         return ElementParserPtr(new AccountProviderParser(m_account));
2505     }
2506
2507     AccountParser(ConfigParserData& data) :
2508         ElementParser(),
2509         m_data(data),
2510         m_account(data.accountProvider),
2511         m_properNamespace(false),
2512         m_multiSupport(false)
2513     {}
2514
2515   private:
2516     ConfigParserData& m_data;
2517     ConfigParserData::AccountProvider& m_account;
2518     bool m_properNamespace;
2519     bool m_multiSupport;
2520 };
2521
2522 class MetadataParser : public ElementParser
2523 {
2524   public:
2525     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2526                                         const DPL::String& /*name*/)
2527     {
2528         return &IgnoringParser::Create; //ignore unknown according to w3c
2529     }
2530
2531     virtual void Accept(const XmlAttribute& attribute)
2532     {
2533         if (m_properNamespace) {
2534             if (attribute.name == L"key") {
2535                 m_key = attribute.value;
2536             } else if (attribute.name == L"value") {
2537                 m_value = attribute.value;
2538             }
2539         }
2540     }
2541
2542     virtual void Accept(const Element& element)
2543     {
2544         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2545             m_properNamespace = true;
2546         }
2547     }
2548
2549     virtual void Accept(const Text& /*text*/)
2550     {
2551         ThrowMsg(Exception::ParseError, "param element must be empty");
2552     }
2553
2554     virtual void Verify()
2555     {
2556         if (m_key.IsNull()) {
2557             LogWarning("metadata element must have key attribute");
2558             return;
2559         }
2560         NormalizeString(m_key);
2561         NormalizeString(m_value);
2562         ConfigParserData::Metadata metaData(m_key, m_value);
2563         FOREACH(it, m_data.metadataList) {
2564             if (!DPL::StringCompare(*it->key, *m_key)) {
2565                 LogError("Key isn't unique");
2566                 return;
2567             }
2568         }
2569         m_data.metadataList.push_back(metaData);
2570     }
2571
2572     MetadataParser(ConfigParserData& data) :
2573         ElementParser(),
2574         m_data(data),
2575         m_properNamespace(false)
2576     {}
2577
2578   private:
2579     DPL::OptionalString m_key;
2580     DPL::OptionalString m_value;
2581     ConfigParserData& m_data;
2582     bool m_properNamespace;
2583 };
2584
2585 ElementParser::ActionFunc WidgetParser::GetElementParser(
2586     const DPL::String& /*ns*/,
2587     const DPL::String& name)
2588 {
2589     FuncMap::const_iterator it = m_map.find(name);
2590     if (it != m_map.end()) {
2591         return it->second;
2592     } else {
2593         return &IgnoringParser::Create; //ignore unknown according to w3c
2594     }
2595 }
2596
2597 WidgetParser::WidgetParser(ConfigParserData& data) :
2598     m_data(data),
2599     m_textDirection(Unicode::EMPTY)
2600 {
2601     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2602     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2603     m_map[L"description"] =
2604         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2605     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2606     m_map[L"license"] =
2607         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2608     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2609     m_map[L"content"] =
2610         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2611     m_map[L"preference"] =
2612         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2613     m_map[L"setting"] =
2614         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2615     m_map[L"application"] = DPL::MakeDelegate(
2616             this,
2617             &WidgetParser::
2618                 OnApplicationElement);
2619     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2620     m_map[L"background"] = DPL::MakeDelegate(this,
2621                                              &WidgetParser::OnBackgroundElement);
2622     m_map[L"privilege"] = DPL::MakeDelegate(this,
2623                                             &WidgetParser::OnPrivilegeElement);
2624     m_map[L"app-control"] = DPL::MakeDelegate(
2625             this,
2626             &WidgetParser::
2627                 OnAppControlElement);
2628     m_map[L"category"] = DPL::MakeDelegate(this,
2629                                            &WidgetParser::OnCategoryElement);
2630     m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
2631 #ifdef CSP_ENABLED
2632     m_map[L"content-security-policy"] = DPL::MakeDelegate(
2633             this,
2634             &WidgetParser::
2635                 OnCspElement);
2636     m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
2637             this,
2638             &WidgetParser::
2639                 OnCspReportOnlyElement);
2640 #endif
2641 #ifdef ALLOW_NAVIGATION_ENABLED
2642     m_map[L"allow-navigation"] =
2643         DPL::MakeDelegate(this, &WidgetParser::OnAllowNavigationElement);
2644 #endif
2645     m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
2646     m_map[L"metadata"] = DPL::MakeDelegate(this, &WidgetParser::OnMetadataElement);
2647 }
2648
2649 ElementParserPtr WidgetParser::OnNameElement()
2650 {
2651     return ElementParserPtr(new NameParser(m_textDirection, m_data));
2652 }
2653
2654 ElementParserPtr WidgetParser::OnAccessElement()
2655 {
2656     return ElementParserPtr(new AccessParser(m_data));
2657 }
2658
2659 ElementParserPtr WidgetParser::OnDescriptionElement()
2660 {
2661     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2662 }
2663
2664 ElementParserPtr WidgetParser::OnAuthorElement()
2665 {
2666     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2667 }
2668
2669 ElementParserPtr WidgetParser::OnLicenseElement()
2670 {
2671     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2672 }
2673
2674 ElementParserPtr WidgetParser::OnIconElement()
2675 {
2676     return ElementParserPtr(new IconParser(m_data));
2677 }
2678
2679 ElementParserPtr WidgetParser::OnContentElement()
2680 {
2681     return ElementParserPtr(new ContentParser(m_data));
2682 }
2683
2684 ElementParserPtr WidgetParser::OnPreferenceElement()
2685 {
2686     return ElementParserPtr(new PreferenceParser(m_data));
2687 }
2688
2689 ElementParserPtr WidgetParser::OnSettingElement()
2690 {
2691     return ElementParserPtr(new SettingParser(m_data));
2692 }
2693
2694 ElementParserPtr WidgetParser::OnApplicationElement()
2695 {
2696     return ElementParserPtr(new ApplicationParser(m_data));
2697 }
2698
2699 ElementParserPtr WidgetParser::OnSplashElement()
2700 {
2701     return ElementParserPtr(new SplashParser(m_data));
2702 }
2703
2704 ElementParserPtr WidgetParser::OnBackgroundElement()
2705 {
2706     return ElementParserPtr(new BackgroundParser(m_data));
2707 }
2708
2709 ElementParserPtr WidgetParser::OnPrivilegeElement()
2710 {
2711     return ElementParserPtr(new PrivilegeParser(m_data));
2712 }
2713
2714 ElementParserPtr WidgetParser::OnAppControlElement()
2715 {
2716     return ElementParserPtr(new AppControlParser(m_data));
2717 }
2718
2719 ElementParserPtr WidgetParser::OnCategoryElement()
2720 {
2721     return ElementParserPtr(new CategoryParser(m_data));
2722 }
2723
2724 ElementParserPtr WidgetParser::OnAppWidgetElement()
2725 {
2726     return ElementParserPtr(new AppWidgetParser(m_data));
2727 }
2728
2729 ElementParserPtr WidgetParser::OnCspElement()
2730 {
2731     return ElementParserPtr(new CspParser(m_data));
2732 }
2733
2734 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
2735 {
2736     return ElementParserPtr(new CspReportOnlyParser(m_data));
2737 }
2738
2739 ElementParserPtr WidgetParser::OnAllowNavigationElement()
2740 {
2741     return ElementParserPtr(new AllowNavigationParser(m_data));
2742 }
2743
2744 ElementParserPtr WidgetParser::OnAccountElement()
2745 {
2746     return ElementParserPtr(new AccountParser(m_data));
2747 }
2748
2749 ElementParserPtr WidgetParser::OnMetadataElement()
2750 {
2751     return ElementParserPtr(new MetadataParser(m_data));
2752 }
2753
2754 void WidgetParser::Accept(const Element& element)
2755 {
2756     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2757         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2758     {
2759         ThrowMsg(Exception::ParseError,
2760                  "Wrong xml namespace for widget element");
2761     }
2762 }
2763
2764 void WidgetParser::Accept(const Text& /*text*/)
2765 {
2766     ThrowMsg(Exception::ParseError, "widged element must be empty");
2767 }
2768
2769 void WidgetParser::Accept(const XmlAttribute& attribute)
2770 {
2771     if (attribute.name == L"id") {
2772         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2773         //If may important tests starts to fail this test we will have
2774         //to consider commenting this test out again.
2775         if (iri.Validate()) {
2776             m_data.widget_id = attribute.value;
2777             NormalizeString(m_data.widget_id);
2778         } else {
2779             LogWarning("Widget id validation failed: " << attribute.value);
2780         }
2781     } else if (attribute.name == L"version") {
2782         m_version = attribute.value;
2783         NormalizeString(m_version);
2784     } else if (attribute.name == L"min-version") {
2785         LogInfo("min-version attribute was found. Value: " << attribute.value);
2786         m_minVersion = attribute.value;
2787         NormalizeString(m_minVersion);
2788         m_data.minVersionRequired = m_minVersion;
2789     } else if (attribute.name == L"height") {
2790         DPL::OptionalString value = attribute.value;
2791         NormalizeString(value);
2792         std::string v = DPL::ToUTF8String(*value);
2793
2794         if (!v.empty()) {
2795             unsigned char c = v.c_str()[0];
2796             if (isdigit(c)) {
2797                 int val = 0;
2798                 for (size_t i = 0; i < v.size(); ++i) {
2799                     c = v.c_str()[i];
2800                     if (isdigit(c)) {
2801                         val *= 10;
2802                         val += (c - '0');
2803                     } else {
2804                         break;
2805                     }
2806                 }
2807                 m_data.height = val;
2808             }
2809         }
2810     } else if (attribute.name == L"width") {
2811         DPL::OptionalString value = attribute.value;
2812         NormalizeString(value);
2813         std::string v = DPL::ToUTF8String(*value);
2814
2815         if (!v.empty()) {
2816             unsigned char c = v.c_str()[0];
2817             if (c >= '0' && c <= '9') {
2818                 int val = 0;
2819                 for (size_t i = 0; i < v.size(); ++i) {
2820                     c = v.c_str()[i];
2821                     if (c >= '0' && c <= '9') {
2822                         val *= 10;
2823                         val += (c - '0');
2824                     } else {
2825                         break;
2826                     }
2827                 }
2828                 m_data.width = val;
2829             }
2830         }
2831     } else if (attribute.name == L"viewmodes") {
2832         DPL::Tokenize(attribute.value,
2833                       L" ",
2834                       std::inserter(m_windowModes,
2835                                     m_windowModes.end()),
2836                       true);
2837     } else if (attribute.name == L"dir") {
2838         m_textDirection = Unicode::ParseDirAttribute(attribute);
2839     } else if (L"defaultlocale" == attribute.name) {
2840         if (!m_defaultlocale) {
2841             m_defaultlocale = attribute.value;
2842             NormalizeString(m_defaultlocale);
2843             /* TODO : should check valid defaultlocale */
2844             LogDebug("Default Locale Found " << m_defaultlocale);
2845         } else {
2846             LogWarning("Ignoring subsequent default locale");
2847         }
2848
2849         //Any other value consider as a namespace definition
2850     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2851         LogInfo("Namespace domain: " << attribute.name);
2852         LogInfo("Namespace value: " << attribute.value);
2853         m_nameSpaces[attribute.name] = attribute.value;
2854     } else {
2855         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2856                  ", name=" << attribute.name <<
2857                  ", value=" << attribute.value);
2858     }
2859 }
2860
2861 void WidgetParser::Verify()
2862 {
2863     FOREACH(mode, m_windowModes) {
2864         if (L"windowed" == *mode || L"floating" == *mode ||
2865             L"fullscreen" == *mode || L"maximized" == *mode ||
2866             L"minimized" == *mode)
2867         {
2868             m_data.windowModes.insert(*mode);
2869         }
2870     }
2871     if (!m_version.IsNull()) {
2872         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2873         m_data.version = m_version;
2874     }
2875     m_data.defaultlocale = m_defaultlocale;
2876     FOREACH(ns, m_nameSpaces) {
2877         m_data.nameSpaces.insert(ns->second);
2878     }
2879 }
2880