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