Implement disposition element parser
[platform/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                 LogDebug("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     struct DispositionParser : public ElementParser
1075     {
1076       public:
1077         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1078                                             const DPL::String& /*name*/)
1079         {
1080             return &IgnoringParser::Create;
1081         }
1082
1083         virtual void Accept(const Text& /*text*/)
1084         {}
1085
1086         virtual void Accept(const Element& /*element*/)
1087         {}
1088
1089         virtual void Accept(const XmlAttribute& attribute)
1090         {
1091             if (attribute.name == L"name") {
1092                 if (attribute.value.size() > 0) {
1093                     m_value = attribute.value;
1094                     NormalizeString(m_value);
1095                 }
1096             }
1097         }
1098
1099         virtual void Verify()
1100         {
1101             if (m_value.IsNull() || *m_value == L"") {
1102                 return;
1103             }
1104
1105             DPL::String windowString(L"window");
1106             DPL::String inlineString(L"inline");
1107
1108             if (*m_value == L"window") {
1109                 m_data.m_disposition =
1110                     ConfigParserData::AppControlInfo::Disposition::WINDOW;
1111             } else if (*m_value == L"inline") {
1112                 m_data.m_disposition =
1113                     ConfigParserData::AppControlInfo::Disposition::INLINE;
1114             } else {
1115                 LogDebug("Ignoring dispostion value " <<
1116                          DPL::ToUTF8String(*m_value));
1117             }
1118         }
1119
1120         DispositionParser(ConfigParserData::AppControlInfo& data) :
1121             ElementParser(),
1122             m_properNamespace(false),
1123             m_data(data)
1124         {}
1125
1126       private:
1127         bool m_properNamespace;
1128         DPL::OptionalString m_value;
1129         ConfigParserData::AppControlInfo& m_data;
1130     };
1131
1132     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1133                                         const DPL::String& name)
1134     {
1135         if (name == L"src") {
1136             return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1137         } else if (name == L"operation") {
1138             return DPL::MakeDelegate(this,
1139                                      &AppControlParser::OnOperationElement);
1140         } else if (name == L"uri") {
1141             return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1142         } else if (name == L"mime") {
1143             return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1144         } else if (name == L"disposition") {
1145             return DPL::MakeDelegate(this,
1146                                      &AppControlParser::OnDispositionElement);
1147         } else {
1148             return &IgnoringParser::Create; //ignore unknown according to w3c
1149         }
1150     }
1151
1152     virtual void Accept(const XmlAttribute& /*attribute*/)
1153     {}
1154
1155     virtual void Accept(const Element& element)
1156     {
1157         LogWarning("namespace for app service = " << element.ns);
1158         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1159             ThrowMsg(Exception::ParseError,
1160                      "Wrong xml namespace for widget element");
1161         }
1162     }
1163
1164     virtual void Accept(const Text& /*text*/)
1165     {
1166         ThrowMsg(Exception::ParseError, "param element must be empty");
1167     }
1168
1169     virtual void Verify()
1170     {
1171         if (m_appControl.m_src == L"") {
1172             ThrowMsg(Exception::ParseError, "service element must have src element");
1173         }
1174
1175         if (m_appControl.m_operation == L"") {
1176             ThrowMsg(Exception::ParseError, "service element must have operation element");
1177         }
1178
1179         m_data.appControlList.push_back(m_appControl);
1180     }
1181
1182     ElementParserPtr OnSourceElement()
1183     {
1184         return ElementParserPtr(new SourceParser(m_appControl));
1185     }
1186
1187     ElementParserPtr OnOperationElement()
1188     {
1189         return ElementParserPtr(new OperationParser(m_appControl));
1190     }
1191
1192     ElementParserPtr OnUriElement()
1193     {
1194         return ElementParserPtr(new UriParser(m_appControl));
1195     }
1196
1197     ElementParserPtr OnMimeElement()
1198     {
1199         return ElementParserPtr(new MimeParser(m_appControl));
1200     }
1201
1202     ElementParserPtr OnDispositionElement()
1203     {
1204         return ElementParserPtr(new DispositionParser(m_appControl));
1205     }
1206
1207     AppControlParser(ConfigParserData& data) :
1208         ElementParser(),
1209         m_data(data),
1210         m_appControl(L"")
1211     {}
1212
1213   private:
1214     ConfigParserData& m_data;
1215     ConfigParserData::AppControlInfo m_appControl;
1216 };
1217
1218 class ApplicationParser : public ElementParser
1219 {
1220   public:
1221     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1222                                         const DPL::String& /*name*/)
1223     {
1224         return &IgnoringParser::Create; //ignore unknown according to w3c
1225     }
1226
1227     virtual void Accept(const Text& /*text*/)
1228     {
1229         if (m_properNamespace) {
1230             ThrowMsg(Exception::ParseError, "application element must be empty");
1231         }
1232     }
1233
1234     virtual void Accept(const Element& element)
1235     {
1236         if (element.ns ==
1237             ConfigurationNamespace::TizenWebAppNamespaceName)
1238         {
1239             m_properNamespace = true;
1240         }
1241     }
1242
1243     virtual void Accept(const XmlAttribute& attribute)
1244     {
1245         if (m_properNamespace) {
1246             if (attribute.name == L"id") {
1247                 m_id = attribute.value;
1248                 NormalizeAndTrimSpaceString(m_id);
1249             } else if (attribute.name == L"package") {
1250                 m_package = attribute.value;
1251             } else if (attribute.name == L"required_version") {
1252                 m_version = attribute.value;
1253                 NormalizeString(m_version);
1254             } else {
1255                 ThrowMsg(Exception::ParseError,
1256                          "unknown attribute '" +
1257                          DPL::ToUTF8String(attribute.name) +
1258                          "' in application element");
1259             }
1260         }
1261     }
1262
1263     virtual void Verify()
1264     {
1265         VerifyIdAndPackage();
1266         VerifyVersion();
1267     }
1268
1269     ApplicationParser(ConfigParserData& data) :
1270         ElementParser(),
1271         m_data(data),
1272         m_id(DPL::OptionalString::Null),
1273         m_version(DPL::OptionalString::Null),
1274         m_properNamespace(false)
1275     {}
1276
1277     static const char* const REGEXP_ID;
1278
1279   private:
1280     void VerifyIdAndPackage()
1281     {
1282         if (!m_package)
1283         {
1284             ThrowMsg(Exception::ParseError,
1285                      "application element must have package attribute");
1286         }
1287         else
1288         {
1289             pcrecpp::RE re(REGEXP_PACKAGE);
1290             if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
1291             {
1292                 ThrowMsg(Exception::ParseError,
1293                          "invalid format of package attribute");
1294             }
1295         }
1296
1297         if (!m_id) {
1298             ThrowMsg(Exception::ParseError,
1299                      "application element must have id attribute");
1300         }
1301         else
1302         {
1303             std::string package;
1304             pcrecpp::RE re(REGEXP_ID);
1305             if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
1306             {
1307                 ThrowMsg(Exception::ParseError,
1308                          "invalid format of id attribute");
1309             }
1310             if (package != DPL::ToUTF8String(*m_package))
1311             {
1312                 ThrowMsg(Exception::ParseError,
1313                          "invalid package prefix in id attribute");
1314             }
1315         }
1316
1317         m_data.tizenAppId = m_id;
1318         m_data.tizenPkgId = m_package;
1319     }
1320
1321     void VerifyVersion()
1322     {
1323         if (!m_version)
1324         {
1325             ThrowMsg(Exception::ParseError,
1326                      "application element must have required_version attribute");
1327         }
1328         else
1329         {
1330             pcrecpp::RE re(REGEXP_VERSION);
1331             if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
1332             {
1333                 ThrowMsg(Exception::ParseError,
1334                          "invalid format of version attribute");
1335             }
1336         }
1337
1338         m_data.tizenMinVersionRequired = m_version;
1339     }
1340
1341     static const char* const REGEXP_PACKAGE;
1342     static const char* const REGEXP_VERSION;
1343
1344     ConfigParserData& m_data;
1345     DPL::OptionalString m_id;
1346     DPL::OptionalString m_package;
1347     DPL::OptionalString m_version;
1348     bool m_properNamespace;
1349 };
1350
1351 const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
1352 const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
1353 const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)?";
1354
1355 class SplashParser : public ElementParser
1356 {
1357   public:
1358     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1359                                         const DPL::String& /*name*/)
1360     {
1361         return &IgnoringParser::Create; //ignore unknown according to w3c
1362     }
1363
1364     virtual void Accept(const XmlAttribute& attribute)
1365     {
1366         if (m_properNamespace)
1367         {
1368             if (attribute.name == L"src") {
1369                 if (attribute.value.size() > 0) {
1370                     m_src = attribute.value;
1371                 }
1372             }
1373         }
1374     }
1375
1376     virtual void Accept(const Element& element)
1377     {
1378         if (element.ns ==
1379             ConfigurationNamespace::TizenWebAppNamespaceName)
1380         {
1381             m_properNamespace = true;
1382         }
1383     }
1384
1385     virtual void Accept(const Text& /*text*/)
1386     {}
1387
1388     virtual void Verify()
1389     {
1390         if (m_src.IsNull())
1391         {
1392             LogWarning("src attribute of splash element is mandatory - ignoring");
1393             return;
1394         }
1395
1396         m_data.splashImgSrc = m_src;
1397     }
1398
1399     SplashParser(ConfigParserData& data) :
1400         ElementParser(),
1401         m_data(data),
1402         m_properNamespace(false)
1403     {}
1404
1405   private:
1406     DPL::OptionalString m_src;
1407     ConfigParserData& m_data;
1408     bool m_properNamespace;
1409 };
1410
1411 class BackgroundParser : public ElementParser
1412 {
1413   public:
1414     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1415                                         const DPL::String& /*name*/)
1416     {
1417         return &IgnoringParser::Create; //ignore unknown according to w3c
1418     }
1419
1420     virtual void Accept(const XmlAttribute& attribute)
1421     {
1422         if (attribute.name == L"src") {
1423             if (attribute.value.size() > 0) {
1424                 m_src = attribute.value;
1425             }
1426         }
1427     }
1428
1429     virtual void Accept(const Element& /*element*/)
1430     {}
1431
1432     virtual void Accept(const Text& /*text*/)
1433     {}
1434
1435     virtual void Verify()
1436     {
1437         if (m_src.IsNull()) {
1438             LogWarning(
1439                 "src attribute of background element is mandatory - ignoring");
1440             return;
1441         }
1442
1443         m_data.backgroundPage = m_src;
1444     }
1445
1446     explicit BackgroundParser(ConfigParserData& data) :
1447         m_data(data)
1448     {}
1449
1450   private:
1451     DPL::OptionalString m_src;
1452     ConfigParserData& m_data;
1453 };
1454
1455 class PrivilegeParser : public ElementParser
1456 {
1457   public:
1458     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1459                                         const DPL::String& /*name*/)
1460     {
1461         return &IgnoringParser::Create; //ignore unknown according to w3c
1462     }
1463
1464     virtual void Accept(const Text& /*text*/)
1465     {}
1466
1467     virtual void Accept(const Element& element)
1468     {
1469         if (element.ns ==
1470             ConfigurationNamespace::TizenWebAppNamespaceName)
1471         {
1472             m_properNamespace = true;
1473         }
1474         LogDebug("element");
1475     }
1476
1477     virtual void Accept(const XmlAttribute& attribute)
1478     {
1479         if (m_properNamespace) {
1480             if (attribute.name == L"name") {
1481                 m_feature.name = attribute.value;
1482                 m_privilege.name = attribute.value;
1483             }
1484         }
1485     }
1486
1487     virtual void Verify()
1488     {
1489         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1490
1491         if (m_feature.name != L"") {
1492             if (iri.Validate()) {
1493                 if (m_data.featuresList.find(m_feature) ==
1494                     m_data.featuresList.end())
1495                 {
1496                     m_data.featuresList.insert(m_feature);
1497                 } else {
1498                     LogDebug("Ignoring feature with name" <<
1499                         DPL::ToUTF8String(m_feature.name));
1500                 }
1501             }
1502         }
1503
1504         LibIri::Wrapper iriPrivilege(
1505             DPL::ToUTF8String(m_privilege.name).c_str());
1506
1507         if (m_privilege.name != L"") {
1508             if (iriPrivilege.Validate()) {
1509                 if (m_data.privilegeList.find(m_privilege) ==
1510                     m_data.privilegeList.end())
1511                 {
1512                     m_data.privilegeList.insert(m_privilege);
1513                 } else {
1514                     LogDebug("Ignoring privilege with name" <<
1515                              DPL::ToUTF8String(m_privilege.name));
1516                 }
1517             }
1518         }
1519     }
1520
1521     PrivilegeParser(ConfigParserData& data) :
1522         ElementParser(),
1523         m_data(data),
1524         m_feature(L""),
1525         m_privilege(L""),
1526         m_properNamespace(false)
1527     {}
1528
1529   private:
1530     ConfigParserData& m_data;
1531     ConfigParserData::Feature m_feature;
1532     ConfigParserData::Privilege m_privilege;
1533     bool m_properNamespace;
1534 };
1535
1536 class CategoryParser : public ElementParser
1537 {
1538   public:
1539     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1540                                         const DPL::String& /*name*/)
1541     {
1542         return &IgnoringParser::Create; //ignore unknown according to w3c
1543     }
1544
1545     virtual void Accept(const XmlAttribute& attribute)
1546     {
1547         if (attribute.name == L"name") {
1548             if (attribute.value.size() > 0) {
1549                 m_name = attribute.value;
1550             }
1551         }
1552     }
1553
1554     virtual void Accept(const Element& /*element*/)
1555     {}
1556
1557     virtual void Accept(const Text& /*text*/)
1558     {}
1559
1560     virtual void Verify()
1561     {
1562         if (m_name.IsNull()) {
1563             LogWarning(
1564                 "name attribute of category element is mandatory - ignoring");
1565             return;
1566         }
1567
1568         if (m_data.categoryList.find(*m_name) ==
1569             m_data.categoryList.end())
1570         {
1571             m_data.categoryList.insert(*m_name);
1572         }
1573     }
1574
1575     explicit CategoryParser(ConfigParserData& data) :
1576         m_data(data)
1577     {}
1578
1579   private:
1580     DPL::OptionalString m_name;
1581     ConfigParserData& m_data;
1582 };
1583
1584 class AppWidgetParser : public ElementParser
1585 {
1586   public:
1587
1588     struct BoxLabelParser : public ElementParser
1589     {
1590         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1591                                             const DPL::String& /*name*/)
1592         {
1593             return &IgnoringParser::Create; //ignore unknown according to w3c
1594         }
1595
1596         virtual void Accept(const XmlAttribute& attribute)
1597         {
1598             if (m_properNamespace) {
1599                  m_lang = attribute.lang;
1600             }
1601         }
1602         virtual void Accept(const Element& element)
1603         {
1604             if (element.ns ==
1605                 ConfigurationNamespace::TizenWebAppNamespaceName)
1606             {
1607                 m_properNamespace = true;
1608             }
1609         }
1610
1611         virtual void Accept(const Text& text)
1612         {
1613             if (m_properNamespace) {
1614                 m_label = text.value;
1615             }
1616         }
1617
1618         virtual void Verify()
1619         {
1620             std::pair<DPL::String, DPL::String> boxLabel;
1621             if (m_label.empty()) {
1622                 LogWarning("box-label element is empty");
1623                 boxLabel.first = DPL::FromUTF8String("");
1624                 boxLabel.second = DPL::FromUTF8String("");
1625                 m_data.m_label.push_back(boxLabel);
1626             }
1627             else {
1628                 boxLabel.first = m_lang;
1629                 boxLabel.second = m_label;
1630                 m_data.m_label.push_back(boxLabel);
1631             }
1632         }
1633
1634         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1635             ElementParser(),
1636             m_properNamespace(false),
1637             m_data(data)
1638         {}
1639
1640       private:
1641         DPL::String m_lang;
1642         DPL::String m_label;
1643         bool m_properNamespace;
1644         ConfigParserData::LiveboxInfo& m_data;
1645     };
1646
1647     struct BoxIconParser : public ElementParser
1648     {
1649         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1650                                             const DPL::String& /*name*/)
1651         {
1652             return &IgnoringParser::Create; //ignore unknown according to w3c
1653         }
1654
1655         virtual void Accept(const XmlAttribute& attribute)
1656         {
1657             if (m_properNamespace) {
1658                 if (attribute.name == L"src") {
1659                     m_icon = attribute.value;
1660                 }
1661             }
1662         }
1663
1664         virtual void Accept(const Element& element)
1665         {
1666             if (element.ns ==
1667                 ConfigurationNamespace::TizenWebAppNamespaceName)
1668             {
1669                 m_properNamespace = true;
1670             }
1671         }
1672
1673         virtual void Accept(const Text& /*text*/)
1674         {}
1675
1676         virtual void Verify()
1677         {
1678             if (m_icon.empty()) {
1679                 ThrowMsg(Exception::ParseError,
1680                     "src attribute of box-icon element is mandatory - ignoring");
1681             }
1682             m_data.m_icon = m_icon;
1683         }
1684
1685         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1686             ElementParser(),
1687             m_properNamespace(false),
1688             m_data(data)
1689         {}
1690
1691       private:
1692         DPL::String m_icon;
1693         bool m_properNamespace;
1694         ConfigParserData::LiveboxInfo& m_data;
1695     };
1696
1697     struct BoxContentParser : public ElementParser
1698     {
1699         struct BoxSizeParser : public ElementParser
1700         {
1701             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1702                                                 const DPL::String& /*name*/)
1703             {
1704                 return &IgnoringParser::Create; //ignore unknown according to w3c
1705             }
1706
1707             virtual void Accept(const XmlAttribute& attribute)
1708             {
1709                 if (m_properNamespace) {
1710                     if (attribute.name == L"preview") {
1711                         m_preview = attribute.value;
1712                     }
1713                     if (attribute.name == L"use-decoration") {
1714                         m_useDecoration = attribute.value;
1715                     }
1716                 }
1717             }
1718
1719             virtual void Accept(const Element& element)
1720             {
1721                 if (element.ns ==
1722                     ConfigurationNamespace::TizenWebAppNamespaceName)
1723                 {
1724                     m_properNamespace = true;
1725                 }
1726             }
1727
1728             virtual void Accept(const Text& text)
1729             {
1730                 if (m_properNamespace) {
1731                     m_size = text.value;
1732                 }
1733             }
1734
1735             virtual void Verify()
1736             {
1737                 if(m_size.empty()) {
1738                     ThrowMsg(Exception::ParseError,
1739                         "size is mandatory - ignoring");
1740                 }
1741
1742                 ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
1743                 boxSizeInfo.m_size = m_size;
1744                 boxSizeInfo.m_preview = m_preview;
1745                 boxSizeInfo.m_useDecoration = m_useDecoration;
1746                 m_data.m_boxSize.push_back(boxSizeInfo);
1747             }
1748
1749             explicit BoxSizeParser(
1750                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1751                 ElementParser(),
1752                 m_properNamespace(false),
1753                 m_data(data)
1754             {}
1755
1756           private:
1757             DPL::String m_size;
1758             DPL::String m_preview;
1759             DPL::String m_useDecoration;
1760             bool m_properNamespace;
1761             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1762         };
1763
1764         struct PdParser : public ElementParser
1765         {
1766             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1767                                                 const DPL::String& /*name*/)
1768             {
1769                 return &IgnoringParser::Create; //ignore unknown according to w3c
1770             }
1771
1772             virtual void Accept(const XmlAttribute& attribute)
1773             {
1774                 if (m_properNamespace) {
1775                     if (attribute.name == L"src") {
1776                         m_src = attribute.value;
1777                     } else if (attribute.name == L"width") {
1778                         m_width = attribute.value;
1779                     } else if (attribute.name == L"height") {
1780                         m_height = attribute.value;
1781                     } else if (attribute.name == L"fast-open") {
1782                         m_fastOpen= attribute.value;
1783                     }
1784                 }
1785             }
1786
1787             virtual void Accept(const Element& element)
1788             {
1789                 if (element.ns ==
1790                     ConfigurationNamespace::TizenWebAppNamespaceName)
1791                 {
1792                     m_properNamespace = true;
1793                 }
1794             }
1795
1796             virtual void Accept(const Text& /*text*/)
1797             {}
1798
1799             virtual void Verify()
1800             {
1801                 if (m_src.empty()) {
1802                     ThrowMsg(Exception::ParseError,
1803                         "src attribute of pd element is mandatory - ignoring");
1804                 }
1805
1806                 if (m_width.empty()) {
1807                     ThrowMsg(Exception::ParseError,
1808                         "width attribute of pd element is mandatory - ignoring");
1809                 }
1810
1811                 if (m_height.empty()) {
1812                     ThrowMsg(Exception::ParseError,
1813                         "height attribute of pd element is mandatory - ignoring");
1814                 }
1815
1816                 if (ConvertToInt(m_width).IsNull()) {
1817                     ThrowMsg(Exception::ParseError,
1818                         "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
1819                 }
1820
1821
1822                 DPL::OptionalInt height = ConvertToInt(m_height);
1823
1824                 if (height.IsNull()) {
1825                     ThrowMsg(Exception::ParseError,
1826                         "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
1827                 }
1828
1829                 if (*height < 1) {
1830                     m_height = L"1";
1831                     LogDebug("height attribute of pd element shouldn't be less than 1. Changed to 1 from " << *height);
1832                 } else if (*height > 380){
1833                     m_height = L"380";
1834                     LogDebug("height attribute of pd element shouldn't be greater than 380. Changed to 380 from " << *height);
1835                 }
1836
1837                 m_data.m_pdSrc = m_src;
1838                 m_data.m_pdWidth = m_width;
1839                 m_data.m_pdHeight = m_height;
1840                 m_data.m_pdFastOpen = m_fastOpen;
1841             }
1842
1843             explicit PdParser(
1844                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1845                 ElementParser(),
1846                 m_properNamespace(false),
1847                 m_data(data)
1848             {}
1849
1850           private:
1851             DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
1852             {
1853                 char * endptr;
1854                 std::string tempStr = DPL::ToUTF8String(intAsString);
1855                 const char * intAsString_c = tempStr.c_str();
1856                 errno = 0;
1857                 long int intAsString_i = strtol(intAsString_c, &endptr, 10);
1858
1859                 if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
1860                         || intAsString_i > INT_MAX || intAsString_i < INT_MIN
1861                         || *endptr != '\0') {
1862                     return DPL::OptionalInt::Null;
1863                 }
1864
1865                 return static_cast<int>(intAsString_i);
1866             }
1867
1868             DPL::String m_src;
1869             DPL::String m_width;
1870             DPL::String m_height;
1871             DPL::String m_fastOpen;
1872
1873             bool m_properNamespace;
1874             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1875         };
1876
1877         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1878                                             const DPL::String& name)
1879         {
1880             if (name == L"box-size") {
1881                 return DPL::MakeDelegate(
1882                            this,
1883                            &AppWidgetParser::BoxContentParser::
1884                                OnBoxSizeElement);
1885             } else if (name == L"pd") {
1886                 return DPL::MakeDelegate(
1887                            this,
1888                            &AppWidgetParser::BoxContentParser::
1889                                OnPdElement);
1890             } else {
1891                 ThrowMsg(Exception::ParseError,
1892                          "No element parser for name: " << name);
1893             }
1894         }
1895
1896         virtual void Accept(const XmlAttribute& attribute)
1897         {
1898             if (m_properNamespace) {
1899                 if (attribute.name == L"src") {
1900                     m_box.m_boxSrc = attribute.value;
1901                 }
1902                 if (attribute.name == L"mouse-event") {
1903                     m_box.m_boxMouseEvent = attribute.value;
1904                 }
1905                 if (attribute.name == L"touch-effect") {
1906                     m_box.m_boxTouchEffect = attribute.value;
1907                 }
1908             }
1909         }
1910
1911         virtual void Accept(const Element& element)
1912         {
1913             if (element.ns ==
1914                 ConfigurationNamespace::TizenWebAppNamespaceName)
1915             {
1916                 m_properNamespace = true;
1917             }
1918         }
1919
1920         virtual void Accept(const Text& /*text*/)
1921         {}
1922
1923         virtual void Verify()
1924         {
1925             if (m_box.m_boxSrc.empty()) {
1926                 ThrowMsg(Exception::ParseError,
1927                     "src attribute of box-content element is mandatory - ignoring");
1928             }
1929
1930             if (!m_box.m_boxMouseEvent.empty() &&
1931                     CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent))
1932             {
1933                 ThrowMsg(Exception::ParseError,
1934                     "mouse-event attribute of box-content element should be true or false - ignoring");
1935             }
1936
1937             if (!m_box.m_boxTouchEffect.empty() &&
1938                     CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect))
1939             {
1940                 ThrowMsg(Exception::ParseError,
1941                     "touch-effect attribute of box-content element should be true or false - ignoring");
1942             }
1943
1944             if (m_box.m_boxMouseEvent.empty()) {
1945                 m_box.m_boxMouseEvent = L"false";
1946             }
1947
1948             if (m_box.m_boxTouchEffect.empty()) {
1949                 m_box.m_boxTouchEffect = L"true";
1950             }
1951
1952             if (m_box.m_boxSize.empty()) {
1953                 ThrowMsg(Exception::ParseError,
1954                     "box-size element of box-content element not found - ignoring");
1955             }
1956
1957             m_data.m_boxInfo = m_box;
1958         }
1959
1960         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1961             ElementParser(),
1962             m_properNamespace(false),
1963             m_data(data)
1964         {}
1965
1966         ElementParserPtr OnBoxSizeElement()
1967         {
1968             return ElementParserPtr(new BoxSizeParser(m_box));
1969         }
1970
1971         ElementParserPtr OnPdElement()
1972         {
1973             return ElementParserPtr(new PdParser(m_box));
1974         }
1975
1976       private:
1977         bool m_properNamespace;
1978         ConfigParserData::LiveboxInfo& m_data;
1979         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1980     };
1981
1982     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1983                                         const DPL::String& name)
1984     {
1985         if (name == L"box-label") {
1986             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
1987         } else if (name == L"box-icon") {
1988             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
1989         } else if (name == L"box-content") {
1990             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
1991         } else {
1992             return &IgnoringParser::Create; //ignore unknown according to w3c
1993         }
1994     }
1995
1996     virtual void Accept(const XmlAttribute& attribute)
1997     {
1998         if (m_properNamespace) {
1999             if (attribute.name == L"id") {
2000                 m_liveboxId = attribute.value;
2001             } else if (attribute.name == L"primary") {
2002                 m_primary = attribute.value;
2003             } else if (attribute.name == L"auto-launch") {
2004                 m_autoLaunch = attribute.value;
2005             } else if (attribute.name == L"update-period") {
2006                 m_updatePeriod = attribute.value;
2007             } else if (attribute.name == L"type") {
2008                 m_type = attribute.value;
2009             }
2010         }
2011     }
2012
2013     virtual void Accept(const Element& element)
2014     {
2015         if (element.ns ==
2016             ConfigurationNamespace::TizenWebAppNamespaceName)
2017         {
2018             m_properNamespace = true;
2019         }
2020     }
2021
2022     virtual void Accept(const Text& /*text*/)
2023     {}
2024
2025     virtual void Verify()
2026     {
2027         if (m_liveboxId.empty()) {
2028             ThrowMsg(Exception::ParseError,
2029                  "app-widget element must have id attribute");
2030         }
2031         else
2032         {
2033             pcrecpp::RE re(REGEXP_ID_STRING.c_str());
2034             if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
2035             {
2036                 ThrowMsg(Exception::ParseError,
2037                      "invalid format of app-widget id attribute");
2038             }
2039         }
2040
2041         if (m_primary.empty())
2042         {
2043             ThrowMsg(Exception::ParseError,
2044                  "app-widget element must have primary attribute");
2045         } else if (CheckIfNotTrueNorFalse(m_primary))
2046         {
2047             ThrowMsg(Exception::ParseError,
2048                 "auto-launch attribute of app-widget element should be true or false - ignoring");
2049         }
2050
2051         if (!m_autoLaunch.empty() &&
2052                 CheckIfNotTrueNorFalse(m_autoLaunch))
2053         {
2054             ThrowMsg(Exception::ParseError,
2055                 "auto-launch attribute of app-widget element should be true or false - ignoring");
2056         }
2057
2058         if (!m_updatePeriod.empty())
2059         {
2060             char * endptr;
2061             errno = 0;
2062             std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
2063
2064             //set standard locale to fix decimal point mark - '.'
2065             std::string currentLocale = setlocale(LC_NUMERIC, NULL);
2066             if (NULL == setlocale(LC_NUMERIC, "C"))
2067                 LogWarning("Failed to change locale to \"C\"");
2068             double updatePeriod = strtod(tempStr.c_str(), &endptr);
2069
2070             //go back to previous locale
2071             if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
2072                 LogWarning("Failed to set previous locale");
2073
2074             if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
2075                     || *endptr != '\0') {
2076                 ThrowMsg(Exception::ParseError,
2077                     "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
2078             } else if (updatePeriod < 1800.0) {
2079                 LogDebug("update-period attribute of app-widget element shouldn't be less than 1800.0 - changed to 1800 from value: " << m_updatePeriod);
2080                 m_updatePeriod = L"1800.0";
2081             }
2082         }
2083
2084         if (m_autoLaunch.empty()) {
2085             m_autoLaunch = L"false";
2086         }
2087
2088         if(m_livebox.m_label.empty()) {
2089             ThrowMsg(Exception::ParseError,
2090                 "box-label element of app-widget element not found - ignoring");
2091         }
2092
2093         if(!m_boxContentFound) {
2094             ThrowMsg(Exception::ParseError,
2095                 "box-content element of app-widget element not found - ignoring");
2096         }
2097
2098         m_livebox.m_liveboxId = m_liveboxId;
2099         m_livebox.m_primary = m_primary;
2100         m_livebox.m_autoLaunch = m_autoLaunch;
2101         m_livebox.m_updatePeriod = m_updatePeriod;
2102         m_livebox.m_type = m_type;
2103
2104         m_data.m_livebox.push_back(m_livebox);
2105     }
2106
2107     explicit AppWidgetParser(ConfigParserData& data) :
2108         ElementParser(),
2109         m_data(data),
2110         m_properNamespace(false),
2111         m_boxContentFound(false)
2112     {
2113         m_livebox = ConfigParserData::LiveboxInfo();
2114     }
2115
2116     ElementParserPtr OnBoxLabelElement()
2117     {
2118
2119         return ElementParserPtr(new BoxLabelParser(m_livebox));
2120     }
2121
2122     ElementParserPtr OnBoxIconElement()
2123     {
2124         return ElementParserPtr(new BoxIconParser(m_livebox));
2125     }
2126
2127     ElementParserPtr OnBoxContentElement()
2128     {
2129         m_boxContentFound = true;
2130         return ElementParserPtr(new BoxContentParser(m_livebox));
2131     }
2132
2133   private:
2134     static std::string REGEXP_ID_STRING;
2135     ConfigParserData& m_data;
2136     ConfigParserData::LiveboxInfo m_livebox;
2137     DPL::String m_liveboxId;
2138     DPL::String m_primary;
2139     DPL::String m_autoLaunch;
2140     DPL::String m_updatePeriod;
2141     DPL::String m_type;
2142     bool m_properNamespace;
2143     bool m_boxContentFound;
2144
2145     static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
2146     {
2147         return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
2148     }
2149 };
2150
2151 std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
2152
2153 class AllowNavigationParser : public ElementParser
2154 {
2155   public:
2156     AllowNavigationParser(ConfigParserData& data) :
2157       ElementParser(),
2158       m_data(data),
2159       m_properNamespace(false)
2160     {}
2161
2162     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2163                                         const DPL::String& /*name*/)
2164     {
2165         return &IgnoringParser::Create; //ignore unknown according to w3c
2166     }
2167
2168     virtual void Accept(const Element& element)
2169     {
2170         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2171             m_properNamespace = true;
2172         }
2173     }
2174
2175     virtual void Accept(const Text& text)
2176     {
2177         if (m_properNamespace)
2178         {
2179             m_origin = text.value;
2180         }
2181     }
2182
2183     virtual void Accept(const XmlAttribute& /*attribute*/)
2184     {
2185     }
2186
2187     virtual void Verify()
2188     {
2189         if (m_data.allowNavigationEncountered || !m_properNamespace)
2190         {
2191             return;
2192         }
2193         m_data.allowNavigationEncountered = true;
2194
2195         if (m_origin.IsNull()) {
2196             LogWarning("data is empty");
2197             return;
2198         }
2199
2200         char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
2201         char* ptr = strtok(data," ");
2202         while (ptr != NULL) {
2203             std::string origin = ptr;
2204             ptr = strtok(NULL," ");
2205             if(origin == "*") {
2206                 ConfigParserData::AllowNavigationInfo info(L"*", L"*");
2207                 m_data.allowNavigationInfoList.push_back(info);
2208                 continue;
2209             }
2210
2211             DPL::ScopedPtr<iri_t> iri(iri_parse(origin.c_str()));
2212             if (!iri->host || strlen(iri->host) == 0) {
2213                 // input origin should has schem and host
2214                 // in case of file scheme path is filled
2215                 // "http://"
2216                 LogWarning("input origin isn't verified");
2217                 continue;
2218             }
2219             DPL::String scheme = L"*";
2220             if (iri->scheme && strlen(iri->scheme) != 0) {
2221                 scheme = DPL::FromUTF8String(iri->scheme);
2222             }
2223             ConfigParserData::AllowNavigationInfo info(
2224                 scheme,
2225                 DPL::FromUTF8String(iri->host));
2226             m_data.allowNavigationInfoList.push_back(info);
2227         }
2228         free(data);
2229     }
2230
2231   private:
2232     DPL::OptionalString m_origin;
2233     ConfigParserData& m_data;
2234     bool m_properNamespace;
2235 };
2236
2237 class CspParser : public ElementParser
2238 {
2239   public:
2240     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2241                                         const DPL::String& /*name*/)
2242     {
2243         return &IgnoringParser::Create; //ignore unknown according to w3c
2244     }
2245
2246     CspParser(ConfigParserData& data) :
2247         ElementParser(),
2248         m_data(data),
2249         m_properNamespace(false)
2250     {}
2251
2252     virtual void Accept(const Element& element)
2253     {
2254         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2255             m_properNamespace = true;
2256         }
2257     }
2258
2259     virtual void Accept(const XmlAttribute& /*attribute*/)
2260     {}
2261
2262     virtual void Accept(const Text& text)
2263     {
2264         if (m_properNamespace) {
2265             m_policy = text.value;
2266         }
2267     }
2268
2269     virtual void Verify()
2270     {
2271         if (!m_policy.IsNull()) {
2272             m_data.cspPolicy = *m_policy;
2273         }
2274     }
2275
2276   private:
2277     ConfigParserData& m_data;
2278     bool m_properNamespace;
2279     DPL::OptionalString m_policy;
2280 };
2281
2282 class CspReportOnlyParser : public ElementParser
2283 {
2284   public:
2285     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2286                                         const DPL::String& /*name*/)
2287     {
2288         return &IgnoringParser::Create; //ignore unknown according to w3c
2289     }
2290
2291     CspReportOnlyParser(ConfigParserData& data) :
2292         ElementParser(),
2293         m_data(data),
2294         m_properNamespace(false)
2295     {}
2296
2297     virtual void Accept(const Element& element)
2298     {
2299         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2300             m_properNamespace = true;
2301         }
2302     }
2303
2304     virtual void Accept(const XmlAttribute& /*attribute*/)
2305     {}
2306
2307     virtual void Accept(const Text& text)
2308     {
2309         if (m_properNamespace) {
2310             m_policy = text.value;
2311         }
2312     }
2313
2314     virtual void Verify()
2315     {
2316         if (!m_policy.IsNull()) {
2317             m_data.cspPolicyReportOnly = *m_policy;
2318         }
2319     }
2320
2321   private:
2322     ConfigParserData& m_data;
2323     bool m_properNamespace;
2324     DPL::OptionalString m_policy;
2325 };
2326
2327 class AccountParser : public ElementParser
2328 {
2329   public:
2330     struct AccountProviderParser : public ElementParser
2331     {
2332       public:
2333
2334           struct IconParser : public ElementParser
2335         {
2336             public:
2337                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2338                         const DPL::String& /*name*/)
2339                 {
2340                     return &IgnoringParser::Create; //ignore unknown according to w3c
2341                 }
2342
2343                 virtual void Accept(const Text& text)
2344                 {
2345                     if (text.value == L"") {
2346                         return;
2347                     }
2348                     m_value = text.value;
2349                 }
2350
2351                 virtual void Accept(const Element& /*element*/)
2352                 {}
2353
2354                 virtual void Accept(const XmlAttribute& attribute)
2355                 {
2356                     if (attribute.name == L"section") {
2357                         if (attribute.value == L"account") {
2358                             m_type = ConfigParserData::IconSectionType::DefaultIcon;
2359                         } else if (attribute.value == L"account-small") {
2360                             m_type = ConfigParserData::IconSectionType::SmallIcon;
2361                         }
2362                     }
2363                 }
2364
2365                 virtual void Verify()
2366                 {
2367                     if (m_value.IsNull() || *m_value == L"") {
2368                         return;
2369                     }
2370
2371                     std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2372                     icon.first = m_type;
2373                     icon.second = *m_value;
2374
2375                     m_data.m_iconSet.insert(icon);
2376                 }
2377
2378                 IconParser(ConfigParserData::AccountProvider& data) :
2379                     ElementParser(),
2380                     m_properNamespace(false),
2381                     m_type(ConfigParserData::DefaultIcon),
2382                     m_data(data)
2383             {}
2384
2385             private:
2386                 bool m_properNamespace;
2387                 ConfigParserData::IconSectionType m_type;
2388                 ConfigParserData::AccountProvider& m_data;
2389                 DPL::OptionalString m_value;
2390         };
2391
2392           struct DisplayNameParser : public ElementParser
2393         {
2394             public:
2395                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2396                         const DPL::String& /*name*/)
2397                 {
2398                     return &IgnoringParser::Create; //ignore unknown according to w3c
2399                 }
2400
2401                 virtual void Accept(const Text& text)
2402                 {
2403                     if (text.value == L"") {
2404                         return;
2405                     }
2406                     m_value = text.value;
2407                 }
2408
2409                 virtual void Accept(const Element& element)
2410                 {
2411                     m_lang = element.lang;
2412                     m_value= L"";
2413                 }
2414
2415                 virtual void Accept(const XmlAttribute& /*attribute*/)
2416                 {}
2417
2418                 virtual void Verify()
2419                 {
2420                     if (m_value.IsNull() || *m_value == L"") {
2421                         return;
2422                     }
2423
2424                     std::pair<DPL::String, DPL::String> name;
2425                     name.first = *m_lang;
2426                     name.second = *m_value;
2427
2428                     m_data.m_displayNameSet.insert(name);
2429                 }
2430
2431                 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2432                     ElementParser(),
2433                     m_properNamespace(false),
2434                     m_data(data)
2435             {}
2436
2437             private:
2438                 bool m_properNamespace;
2439                 DPL::OptionalString m_lang;
2440                 DPL::OptionalString m_value;
2441                 ConfigParserData::AccountProvider& m_data;
2442         };
2443
2444           struct CapabilityParser : public ElementParser
2445         {
2446             public:
2447                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2448                         const DPL::String& /*name*/)
2449                 {
2450                     return &IgnoringParser::Create; //ignore unknown according to w3c
2451                 }
2452
2453                 virtual void Accept(const Text& text)
2454                 {
2455                     if (text.value == L"") {
2456                         return;
2457                     }
2458                     m_value = text.value;
2459                 }
2460
2461                 virtual void Accept(const Element& /*element*/)
2462                 {}
2463
2464                 virtual void Accept(const XmlAttribute& /*attribute*/)
2465                 {}
2466
2467                 virtual void Verify()
2468                 {
2469                     if (m_value.IsNull() || *m_value == L"") {
2470                         return;
2471                     }
2472                     m_data.m_capabilityList.push_back(*m_value);
2473                 }
2474
2475                 CapabilityParser(ConfigParserData::AccountProvider& data) :
2476                     ElementParser(),
2477                     m_properNamespace(false),
2478                     m_data(data)
2479             {}
2480
2481             private:
2482                 bool m_properNamespace;
2483                 DPL::OptionalString m_value;
2484                 ConfigParserData::AccountProvider& m_data;
2485         };
2486           virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2487                   const DPL::String& name)
2488           {
2489               if (name == L"icon") {
2490                   return DPL::MakeDelegate(this, &AccountProviderParser::OnIconElement);
2491               } else if (name == L"display-name") {
2492                   return DPL::MakeDelegate(this,
2493                           &AccountProviderParser::OnDisplayNameElement);
2494               } else if (name == L"capability") {
2495                   return DPL::MakeDelegate(this, &AccountProviderParser::OnCapabilityElement);
2496               } else {
2497                   return &IgnoringParser::Create; //ignore unknown according to w3c
2498               }
2499           }
2500
2501           virtual void Accept(const Text& /*text*/)
2502           {}
2503
2504           virtual void Accept(const Element& /*element*/)
2505           {}
2506
2507           virtual void Accept(const XmlAttribute& attribute)
2508           {
2509               if (attribute.name == L"multiple-accounts-support") {
2510                   if (attribute.value == L"true") {
2511                       m_multiSupport = true;
2512                   }
2513               }
2514           }
2515
2516           virtual void Verify()
2517           {
2518               m_data.m_multiAccountSupport = m_multiSupport;
2519           }
2520
2521           ElementParserPtr OnIconElement()
2522           {
2523               return ElementParserPtr(new IconParser(m_data));
2524           }
2525
2526           ElementParserPtr OnDisplayNameElement()
2527           {
2528               return ElementParserPtr(new DisplayNameParser(m_data));
2529           }
2530
2531           ElementParserPtr OnCapabilityElement()
2532           {
2533               return ElementParserPtr(new CapabilityParser(m_data));
2534           }
2535
2536           AccountProviderParser(ConfigParserData::AccountProvider& data) :
2537               ElementParser(),
2538               m_properNamespace(false),
2539               m_multiSupport(false),
2540               m_data(data)
2541         {}
2542
2543       private:
2544           bool m_properNamespace;
2545           bool m_multiSupport;
2546           ConfigParserData::AccountProvider& m_data;
2547     };
2548
2549     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2550             const DPL::String& name)
2551     {
2552         if (name == L"account-provider") {
2553             return DPL::MakeDelegate(this, &AccountParser::OnProviderElement);
2554         } else {
2555             return &IgnoringParser::Create; //ignore unknown according to w3c
2556         }
2557     }
2558
2559     virtual void Accept(const Element& element)
2560     {
2561         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2562             m_properNamespace = true;
2563         }
2564     }
2565
2566     virtual void Accept(const XmlAttribute& /*attribute*/)
2567     {}
2568
2569     virtual void Accept(const Text& /*text*/)
2570     {}
2571
2572     virtual void Verify()
2573     {}
2574
2575     ElementParserPtr OnProviderElement()
2576     {
2577         return ElementParserPtr(new AccountProviderParser(m_account));
2578     }
2579
2580     AccountParser(ConfigParserData& data) :
2581         ElementParser(),
2582         m_data(data),
2583         m_account(data.accountProvider),
2584         m_properNamespace(false),
2585         m_multiSupport(false)
2586     {}
2587
2588   private:
2589     ConfigParserData& m_data;
2590     ConfigParserData::AccountProvider& m_account;
2591     bool m_properNamespace;
2592     bool m_multiSupport;
2593 };
2594
2595 class MetadataParser : public ElementParser
2596 {
2597   public:
2598     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2599                                         const DPL::String& /*name*/)
2600     {
2601         return &IgnoringParser::Create; //ignore unknown according to w3c
2602     }
2603
2604     virtual void Accept(const XmlAttribute& attribute)
2605     {
2606         if (m_properNamespace) {
2607             if (attribute.name == L"key") {
2608                 m_key = attribute.value;
2609             } else if (attribute.name == L"value") {
2610                 m_value = attribute.value;
2611             }
2612         }
2613     }
2614
2615     virtual void Accept(const Element& element)
2616     {
2617         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2618             m_properNamespace = true;
2619         }
2620     }
2621
2622     virtual void Accept(const Text& /*text*/)
2623     {
2624         ThrowMsg(Exception::ParseError, "param element must be empty");
2625     }
2626
2627     virtual void Verify()
2628     {
2629         if (m_key.IsNull()) {
2630             LogWarning("metadata element must have key attribute");
2631             return;
2632         }
2633         NormalizeString(m_key);
2634         NormalizeString(m_value);
2635         ConfigParserData::Metadata metaData(m_key, m_value);
2636         FOREACH(it, m_data.metadataList) {
2637             if (!DPL::StringCompare(*it->key, *m_key)) {
2638                 LogError("Key isn't unique");
2639                 return;
2640             }
2641         }
2642         m_data.metadataList.push_back(metaData);
2643     }
2644
2645     MetadataParser(ConfigParserData& data) :
2646         ElementParser(),
2647         m_data(data),
2648         m_properNamespace(false)
2649     {}
2650
2651   private:
2652     DPL::OptionalString m_key;
2653     DPL::OptionalString m_value;
2654     ConfigParserData& m_data;
2655     bool m_properNamespace;
2656 };
2657
2658 ElementParser::ActionFunc WidgetParser::GetElementParser(
2659     const DPL::String& /*ns*/,
2660     const DPL::String& name)
2661 {
2662     FuncMap::const_iterator it = m_map.find(name);
2663     if (it != m_map.end()) {
2664         return it->second;
2665     } else {
2666         return &IgnoringParser::Create; //ignore unknown according to w3c
2667     }
2668 }
2669
2670 WidgetParser::WidgetParser(ConfigParserData& data) :
2671     m_data(data),
2672     m_textDirection(Unicode::EMPTY)
2673 {
2674     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2675     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2676     m_map[L"description"] =
2677         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2678     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2679     m_map[L"license"] =
2680         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2681     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2682     m_map[L"content"] =
2683         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2684     m_map[L"preference"] =
2685         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2686     m_map[L"setting"] =
2687         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2688     m_map[L"application"] = DPL::MakeDelegate(
2689             this,
2690             &WidgetParser::
2691                 OnApplicationElement);
2692     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2693     m_map[L"background"] = DPL::MakeDelegate(this,
2694                                              &WidgetParser::OnBackgroundElement);
2695     m_map[L"privilege"] = DPL::MakeDelegate(this,
2696                                             &WidgetParser::OnPrivilegeElement);
2697     m_map[L"app-control"] = DPL::MakeDelegate(
2698             this,
2699             &WidgetParser::
2700                 OnAppControlElement);
2701     m_map[L"category"] = DPL::MakeDelegate(this,
2702                                            &WidgetParser::OnCategoryElement);
2703     m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
2704 #ifdef CSP_ENABLED
2705     m_map[L"content-security-policy"] = DPL::MakeDelegate(
2706             this,
2707             &WidgetParser::
2708                 OnCspElement);
2709     m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
2710             this,
2711             &WidgetParser::
2712                 OnCspReportOnlyElement);
2713 #endif
2714 #ifdef ALLOW_NAVIGATION_ENABLED
2715     m_map[L"allow-navigation"] =
2716         DPL::MakeDelegate(this, &WidgetParser::OnAllowNavigationElement);
2717 #endif
2718     m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
2719     m_map[L"metadata"] = DPL::MakeDelegate(this, &WidgetParser::OnMetadataElement);
2720 }
2721
2722 ElementParserPtr WidgetParser::OnNameElement()
2723 {
2724     return ElementParserPtr(new NameParser(m_textDirection, m_data));
2725 }
2726
2727 ElementParserPtr WidgetParser::OnAccessElement()
2728 {
2729     return ElementParserPtr(new AccessParser(m_data));
2730 }
2731
2732 ElementParserPtr WidgetParser::OnDescriptionElement()
2733 {
2734     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2735 }
2736
2737 ElementParserPtr WidgetParser::OnAuthorElement()
2738 {
2739     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2740 }
2741
2742 ElementParserPtr WidgetParser::OnLicenseElement()
2743 {
2744     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2745 }
2746
2747 ElementParserPtr WidgetParser::OnIconElement()
2748 {
2749     return ElementParserPtr(new IconParser(m_data));
2750 }
2751
2752 ElementParserPtr WidgetParser::OnContentElement()
2753 {
2754     return ElementParserPtr(new ContentParser(m_data));
2755 }
2756
2757 ElementParserPtr WidgetParser::OnPreferenceElement()
2758 {
2759     return ElementParserPtr(new PreferenceParser(m_data));
2760 }
2761
2762 ElementParserPtr WidgetParser::OnSettingElement()
2763 {
2764     return ElementParserPtr(new SettingParser(m_data));
2765 }
2766
2767 ElementParserPtr WidgetParser::OnApplicationElement()
2768 {
2769     return ElementParserPtr(new ApplicationParser(m_data));
2770 }
2771
2772 ElementParserPtr WidgetParser::OnSplashElement()
2773 {
2774     return ElementParserPtr(new SplashParser(m_data));
2775 }
2776
2777 ElementParserPtr WidgetParser::OnBackgroundElement()
2778 {
2779     return ElementParserPtr(new BackgroundParser(m_data));
2780 }
2781
2782 ElementParserPtr WidgetParser::OnPrivilegeElement()
2783 {
2784     return ElementParserPtr(new PrivilegeParser(m_data));
2785 }
2786
2787 ElementParserPtr WidgetParser::OnAppControlElement()
2788 {
2789     return ElementParserPtr(new AppControlParser(m_data));
2790 }
2791
2792 ElementParserPtr WidgetParser::OnCategoryElement()
2793 {
2794     return ElementParserPtr(new CategoryParser(m_data));
2795 }
2796
2797 ElementParserPtr WidgetParser::OnAppWidgetElement()
2798 {
2799     return ElementParserPtr(new AppWidgetParser(m_data));
2800 }
2801
2802 ElementParserPtr WidgetParser::OnCspElement()
2803 {
2804     return ElementParserPtr(new CspParser(m_data));
2805 }
2806
2807 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
2808 {
2809     return ElementParserPtr(new CspReportOnlyParser(m_data));
2810 }
2811
2812 ElementParserPtr WidgetParser::OnAllowNavigationElement()
2813 {
2814     return ElementParserPtr(new AllowNavigationParser(m_data));
2815 }
2816
2817 ElementParserPtr WidgetParser::OnAccountElement()
2818 {
2819     return ElementParserPtr(new AccountParser(m_data));
2820 }
2821
2822 ElementParserPtr WidgetParser::OnMetadataElement()
2823 {
2824     return ElementParserPtr(new MetadataParser(m_data));
2825 }
2826
2827 void WidgetParser::Accept(const Element& element)
2828 {
2829     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2830         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2831     {
2832         ThrowMsg(Exception::ParseError,
2833                  "Wrong xml namespace for widget element");
2834     }
2835 }
2836
2837 void WidgetParser::Accept(const Text& /*text*/)
2838 {
2839     ThrowMsg(Exception::ParseError, "widged element must be empty");
2840 }
2841
2842 void WidgetParser::Accept(const XmlAttribute& attribute)
2843 {
2844     if (attribute.name == L"id") {
2845         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2846         //If may important tests starts to fail this test we will have
2847         //to consider commenting this test out again.
2848         if (iri.Validate()) {
2849             m_data.widget_id = attribute.value;
2850             NormalizeString(m_data.widget_id);
2851         } else {
2852             LogWarning("Widget id validation failed: " << attribute.value);
2853         }
2854     } else if (attribute.name == L"version") {
2855         m_version = attribute.value;
2856         NormalizeString(m_version);
2857     } else if (attribute.name == L"min-version") {
2858         LogDebug("min-version attribute was found. Value: " << attribute.value);
2859         m_minVersion = attribute.value;
2860         NormalizeString(m_minVersion);
2861         m_data.minVersionRequired = m_minVersion;
2862     } else if (attribute.name == L"height") {
2863         DPL::OptionalString value = attribute.value;
2864         NormalizeString(value);
2865         std::string v = DPL::ToUTF8String(*value);
2866
2867         if (!v.empty()) {
2868             unsigned char c = v.c_str()[0];
2869             if (isdigit(c)) {
2870                 int val = 0;
2871                 for (size_t i = 0; i < v.size(); ++i) {
2872                     c = v.c_str()[i];
2873                     if (isdigit(c)) {
2874                         val *= 10;
2875                         val += (c - '0');
2876                     } else {
2877                         break;
2878                     }
2879                 }
2880                 m_data.height = val;
2881             }
2882         }
2883     } else if (attribute.name == L"width") {
2884         DPL::OptionalString value = attribute.value;
2885         NormalizeString(value);
2886         std::string v = DPL::ToUTF8String(*value);
2887
2888         if (!v.empty()) {
2889             unsigned char c = v.c_str()[0];
2890             if (c >= '0' && c <= '9') {
2891                 int val = 0;
2892                 for (size_t i = 0; i < v.size(); ++i) {
2893                     c = v.c_str()[i];
2894                     if (c >= '0' && c <= '9') {
2895                         val *= 10;
2896                         val += (c - '0');
2897                     } else {
2898                         break;
2899                     }
2900                 }
2901                 m_data.width = val;
2902             }
2903         }
2904     } else if (attribute.name == L"viewmodes") {
2905         DPL::Tokenize(attribute.value,
2906                       L" ",
2907                       std::inserter(m_windowModes,
2908                                     m_windowModes.end()),
2909                       true);
2910     } else if (attribute.name == L"dir") {
2911         m_textDirection = Unicode::ParseDirAttribute(attribute);
2912     } else if (L"defaultlocale" == attribute.name) {
2913         if (!m_defaultlocale) {
2914             m_defaultlocale = attribute.value;
2915             NormalizeString(m_defaultlocale);
2916             /* TODO : should check valid defaultlocale */
2917             LogDebug("Default Locale Found " << m_defaultlocale);
2918         } else {
2919             LogWarning("Ignoring subsequent default locale");
2920         }
2921
2922         //Any other value consider as a namespace definition
2923     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2924         LogDebug("Namespace domain: " << attribute.name);
2925         LogDebug("Namespace value: " << attribute.value);
2926         m_nameSpaces[attribute.name] = attribute.value;
2927     } else {
2928         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2929                  ", name=" << attribute.name <<
2930                  ", value=" << attribute.value);
2931     }
2932 }
2933
2934 void WidgetParser::Verify()
2935 {
2936     FOREACH(mode, m_windowModes) {
2937         if (L"windowed" == *mode || L"floating" == *mode ||
2938             L"fullscreen" == *mode || L"maximized" == *mode ||
2939             L"minimized" == *mode)
2940         {
2941             m_data.windowModes.insert(*mode);
2942         }
2943     }
2944     if (!m_version.IsNull()) {
2945         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2946         m_data.version = m_version;
2947     }
2948     m_data.defaultlocale = m_defaultlocale;
2949     FOREACH(ns, m_nameSpaces) {
2950         m_data.nameSpaces.insert(ns->second);
2951     }
2952 }
2953