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