2f12265a0682a4e9a1a4a7365538bcbf0b08071a
[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) && m_encoding.IsNull())
706             {
707                 m_encoding = mimeAttributes[L"charset"];
708             }
709         } else if (attribute.name == L"encoding") {
710             if (!value.empty()) {
711                 m_encoding = value;
712             }
713         }
714     }
715
716     virtual void Verify()
717     {
718         if (m_data.startFileEncountered) {
719             LogWarning("This is not the first encountered "
720                        "'content' element - ignoring.");
721             return;
722         }
723
724         m_data.startFileEncountered = true;
725
726         //we're consciously setting startFile even if m_src is null or invalid.
727         //WidgetConfigurationManager will deal with this.
728         m_data.startFile = m_src;
729
730         if (!!m_src) {
731             m_data.startFileContentType = m_type;
732             if (!!m_encoding) {
733                 m_data.startFileEncoding = m_encoding;
734             } else {
735                 m_data.startFileEncoding = L"UTF-8";
736             }
737         }
738     }
739
740   private:
741     DPL::OptionalString m_src;
742     DPL::OptionalString m_type;
743     DPL::OptionalString m_encoding;
744     ConfigParserData& m_data;
745 };
746
747 class PreferenceParser : public ElementParser
748 {
749   public:
750     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
751                                         const DPL::String& /*name*/)
752     {
753         return &IgnoringParser::Create;
754     }
755
756     virtual void Accept(const XmlAttribute& attribute)
757     {
758         if (attribute.name == L"name") {
759             m_name = attribute.value;
760         } else if (attribute.name == L"value") {
761             m_value = attribute.value;
762         } else if (attribute.name == L"readonly") {
763             if (attribute.value == L"true") {
764                 m_required = true;
765             } else {
766                 m_required = false;
767             }
768         }
769     }
770
771     virtual void Accept(const Element& /*element*/)
772     {}
773
774     virtual void Accept(const Text& /*text*/)
775     {
776         ThrowMsg(Exception::ParseError, "param element must be empty");
777     }
778
779     virtual void Verify()
780     {
781         if (m_name.IsNull()) {
782             LogWarning("preference element must have name attribute");
783             return;
784         }
785         NormalizeString(m_name);
786         NormalizeString(m_value);
787         ConfigParserData::Preference preference(*m_name, m_required);
788         preference.value = m_value;
789         if (m_data.preferencesList.find(preference) ==
790             m_data.preferencesList.end())
791         {
792             m_data.preferencesList.insert(preference);
793         }
794     }
795
796     PreferenceParser(ConfigParserData& data) :
797         ElementParser(),
798         m_required(false),
799         m_data(data)
800     {}
801
802   private:
803     DPL::OptionalString m_name;
804     DPL::OptionalString m_value;
805     bool m_required;
806     ConfigParserData& m_data;
807 };
808
809 class LinkParser : public ElementParser
810 {
811   public:
812     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
813                                         const DPL::String& /*name*/)
814     {
815         return &DenyAllParser::Create;
816     }
817
818     virtual void Accept(const XmlAttribute& attribute)
819     {
820         if (m_properNamespace) {
821             LogDebug("attribute");
822             if (attribute.name == L"rel") {
823                 if (attribute.value != L"describedby") {
824                     ThrowMsg(Exception::ParseError,
825                              "rel attribute must have describedby value");
826                 }
827             } else if (attribute.name == L"type") {} else if (attribute.name ==
828                                                               L"href")
829             {
830                 LogDebug("here is href");
831                 m_href = attribute.value;
832             } else {
833                 ThrowMsg(Exception::ParseError,
834                          "unknown attribute '" +
835                          DPL::ToUTF8String(attribute.name) +
836                          "' in link element");
837             }
838         }
839     }
840
841     virtual void Accept(const Element& element)
842     {
843         if (element.ns ==
844             ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement)
845         {
846             m_properNamespace = true;
847         }
848         LogDebug("element");
849     }
850
851     virtual void Accept(const Text&)
852     {
853         if (m_properNamespace) {
854             LogDebug("text");
855             ThrowMsg(Exception::ParseError, "link element must be empty");
856         }
857     }
858
859     virtual void Verify()
860     {
861         if (!m_href) {
862             ThrowMsg(Exception::ParseError,
863                      "link element must have href attribute");
864         }
865
866         LibIri::Wrapper iri(DPL::ToUTF8String(*m_href).c_str());
867         if (!iri.Validate()) { // TODO: Better uri validator ?
868             ThrowMsg(Exception::ParseError,
869                      "href attribute must be a valid iri/uri/url");
870         }
871     }
872
873     LinkParser(ConfigParserData& data) :
874         ElementParser(),
875         m_properNamespace(false),
876         m_data(data),
877         m_href(DPL::OptionalString::Null)
878     {}
879
880   private:
881     bool m_properNamespace;
882     ConfigParserData& m_data;
883     DPL::OptionalString m_href;
884 };
885
886 class SettingParser : public ElementParser
887 {
888   public:
889     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
890                                         const DPL::String& /*name*/)
891     {
892         return &IgnoringParser::Create;
893     }
894
895     virtual void Accept(const Text& /*text*/)
896     {}
897
898     virtual void Accept(const Element& /*element*/)
899     {}
900
901     virtual void Accept(const XmlAttribute& attribute)
902     {
903         m_setting.m_name = attribute.name;
904         m_setting.m_value = attribute.value;
905         m_data.settingsList.insert(m_setting);
906     }
907
908     virtual void Verify()
909     {}
910
911     SettingParser(ConfigParserData& data) :
912         ElementParser(),
913         m_data(data),
914         m_setting(L"", L"")
915     {}
916
917   private:
918     ConfigParserData& m_data;
919     ConfigParserData::Setting m_setting;
920 };
921
922 class AppServiceParser : public ElementParser
923 {
924   public:
925     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
926                                         const DPL::String& /*name*/)
927     {
928         return &IgnoringParser::Create;
929     }
930
931     virtual void Accept(const XmlAttribute& attribute)
932     {
933         if (attribute.name == L"src") {
934             m_src = attribute.value;
935         } else if (attribute.name == L"operation") {
936             m_operation = attribute.value;
937         } else if (attribute.name == L"scheme") {
938             m_scheme = attribute.value;
939         } else if (attribute.name == L"mime") {
940             m_mime = attribute.value;
941         } else if (attribute.name == L"disposition") {
942             if (attribute.value == L"inline")
943                 m_disposition =
944                     ConfigParserData::ServiceInfo::Disposition::INLINE;
945         }
946     }
947
948     virtual void Accept(const Element& element)
949     {
950         LogWarning("namespace for app service = " << element.ns);
951         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
952             ThrowMsg(Exception::ParseError,
953                      "Wrong xml namespace for widget element");
954         }
955     }
956
957     virtual void Accept(const Text& /*text*/)
958     {
959         ThrowMsg(Exception::ParseError, "param element must be empty");
960     }
961
962     virtual void Verify()
963     {
964         if (m_src.IsNull()) {
965             LogWarning("service element must have target attribute");
966             return;
967         } else if (m_operation.IsNull()) {
968             LogWarning("service element must have operation attribute");
969             return;
970         }
971         NormalizeString(m_src);
972         NormalizeString(m_operation);
973         NormalizeString(m_scheme);
974         NormalizeString(m_mime);
975
976         // exception
977         DPL::String ignoreUri(L"file");
978
979         if (!m_scheme.IsNull() && *m_scheme == ignoreUri)
980         {
981             LogInfo("exception : '" << *m_scheme << "' scheme will be ignored.");
982             m_scheme = DPL::OptionalString::Null;
983         }
984
985         // verify duplicate element
986         DPL::String wildString(L"*/*");
987         DPL::String nullString(L"");
988         ConfigParserData::ServiceInfo serviceInfo(
989             m_src.IsNull() ? nullString : *m_src,
990             m_operation.IsNull() ? nullString : *m_operation,
991             m_scheme.IsNull() ? nullString : *m_scheme,
992             m_mime.IsNull() ? nullString : *m_mime,
993             m_disposition);
994
995         FOREACH(iterator, m_data.appServiceList) {
996             if (iterator->m_operation == serviceInfo.m_operation &&
997                 // check scheme
998                 (iterator->m_scheme == serviceInfo.m_scheme ||
999                  // check input scheme is "*/*" case
1000                  (iterator->m_scheme == wildString &&
1001                   serviceInfo.m_scheme != nullString) ||
1002                  // check iterator scheme is "*/*" case
1003                  (serviceInfo.m_scheme == wildString &&
1004                   iterator->m_scheme != nullString)) &&
1005
1006                 (iterator->m_mime == serviceInfo.m_mime ||
1007                  // check input mime is "*/*" case
1008                  (iterator->m_mime == wildString &&
1009                   serviceInfo.m_mime != nullString) ||
1010                  // check iterator mime is "*/*" case
1011                  (serviceInfo.m_mime == wildString &&
1012                   iterator->m_mime != nullString)))
1013             {
1014                 ThrowMsg(Exception::ParseError,
1015                          "service operation is duplicated " +
1016                          DPL::ToUTF8String(*m_operation));
1017             }
1018         }
1019         m_data.appServiceList.push_back(serviceInfo);
1020     }
1021
1022     AppServiceParser(ConfigParserData& data) :
1023         ElementParser(),
1024         m_src(DPL::OptionalString::Null),
1025         m_operation(DPL::OptionalString::Null),
1026         m_scheme(DPL::OptionalString::Null),
1027         m_mime(DPL::OptionalString::Null),
1028         m_disposition(ConfigParserData::ServiceInfo::Disposition::WINDOW),
1029         m_data(data)
1030     {}
1031
1032   private:
1033     DPL::OptionalString m_src;
1034     DPL::OptionalString m_operation;
1035     DPL::OptionalString m_scheme;
1036     DPL::OptionalString m_mime;
1037     ConfigParserData::ServiceInfo::Disposition m_disposition;
1038     ConfigParserData& m_data;
1039 };
1040
1041 class AppControlParser : public ElementParser
1042 {
1043   public:
1044     struct SourceParser : public ElementParser
1045     {
1046       public:
1047         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1048                                             const DPL::String& /*name*/)
1049         {
1050             return &IgnoringParser::Create;
1051         }
1052
1053         virtual void Accept(const Text& /*text*/)
1054         {}
1055
1056         virtual void Accept(const Element& /*element*/)
1057         {}
1058
1059         virtual void Accept(const XmlAttribute& attribute)
1060         {
1061             if (attribute.name == L"name") {
1062                 if (attribute.value.size() > 0) {
1063                     m_value = attribute.value;
1064                     NormalizeString(m_value);
1065                 }
1066             }
1067         }
1068
1069         virtual void Verify()
1070         {
1071             if (m_value.IsNull() || *m_value == L"") {
1072                 return;
1073             }
1074
1075             m_data.m_src = *m_value;
1076         }
1077
1078         SourceParser(ConfigParserData::AppControlInfo& data) :
1079             ElementParser(),
1080             m_properNamespace(false),
1081             m_data(data)
1082         {}
1083
1084       private:
1085         bool m_properNamespace;
1086         DPL::OptionalString m_value;
1087         ConfigParserData::AppControlInfo& m_data;
1088     };
1089
1090     struct OperationParser : public ElementParser
1091     {
1092       public:
1093         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1094                                             const DPL::String& /*name*/)
1095         {
1096             return &IgnoringParser::Create;
1097         }
1098
1099         virtual void Accept(const Text& /*text*/)
1100         {}
1101
1102         virtual void Accept(const Element& /*element*/)
1103         {}
1104
1105         virtual void Accept(const XmlAttribute& attribute)
1106         {
1107             if (attribute.name == L"name") {
1108                 if (attribute.value.size() > 0) {
1109                     m_value = attribute.value;
1110                     NormalizeString(m_value);
1111                 }
1112             }
1113         }
1114
1115         virtual void Verify()
1116         {
1117             if (m_value.IsNull() || *m_value == L"") {
1118                 return;
1119             }
1120
1121             m_data.m_operation = *m_value;
1122         }
1123
1124         OperationParser(ConfigParserData::AppControlInfo& data) :
1125             ElementParser(),
1126             m_properNamespace(false),
1127             m_data(data)
1128         {}
1129
1130       private:
1131         bool m_properNamespace;
1132         DPL::OptionalString m_value;
1133         ConfigParserData::AppControlInfo& m_data;
1134     };
1135
1136     struct UriParser : public ElementParser
1137     {
1138       public:
1139         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1140                                             const DPL::String& /*name*/)
1141         {
1142             return &IgnoringParser::Create;
1143         }
1144
1145         virtual void Accept(const Text& /*text*/)
1146         {}
1147
1148         virtual void Accept(const Element& /*element*/)
1149         {}
1150
1151         virtual void Accept(const XmlAttribute& attribute)
1152         {
1153             if (attribute.name == L"name") {
1154                 if (attribute.value.size() > 0) {
1155                     m_value = attribute.value;
1156                     NormalizeString(m_value);
1157                 }
1158             }
1159         }
1160
1161         virtual void Verify()
1162         {
1163             // exception
1164             DPL::String ignoreUri(L"file");
1165
1166             if (!m_value.IsNull() && *m_value == ignoreUri)
1167             {
1168                 LogInfo("exception : '" << *m_value << "' scheme will be ignored.");
1169                 m_value = DPL::OptionalString::Null;
1170             }
1171
1172             if (m_value.IsNull() || *m_value == L"") {
1173                 return;
1174             }
1175
1176             DPL::String wildString(L"*/*");
1177             if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
1178                 && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
1179             {
1180                 m_data.m_uriList.insert(*m_value);
1181             } else {
1182                 LogDebug("Ignoring uri with name" <<
1183                          DPL::ToUTF8String(*m_value));
1184             }
1185         }
1186
1187         UriParser(ConfigParserData::AppControlInfo& data) :
1188             ElementParser(),
1189             m_properNamespace(false),
1190             m_data(data)
1191         {}
1192
1193       private:
1194         bool m_properNamespace;
1195         DPL::OptionalString m_value;
1196         ConfigParserData::AppControlInfo& m_data;
1197     };
1198
1199     struct MimeParser : public ElementParser
1200     {
1201       public:
1202         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1203                                             const DPL::String& /*name*/)
1204         {
1205             return &IgnoringParser::Create;
1206         }
1207
1208         virtual void Accept(const Text& /*text*/)
1209         {}
1210
1211         virtual void Accept(const Element& /*element*/)
1212         {}
1213
1214         virtual void Accept(const XmlAttribute& attribute)
1215         {
1216             if (attribute.name == L"name") {
1217                 if (attribute.value.size() > 0) {
1218                     m_value = attribute.value;
1219                     NormalizeString(m_value);
1220                 }
1221             }
1222         }
1223
1224         virtual void Verify()
1225         {
1226             if (m_value.IsNull() || *m_value == L"") {
1227                 return;
1228             }
1229
1230             DPL::String wildString(L"*/*");
1231             if ((m_data.m_mimeList.find(wildString) ==
1232                  m_data.m_mimeList.end())
1233                 && (m_data.m_mimeList.find(*m_value) ==
1234                     m_data.m_mimeList.end()))
1235             {
1236                 m_data.m_mimeList.insert(*m_value);
1237             } else {
1238                 LogDebug("Ignoring mime with name" <<
1239                          DPL::ToUTF8String(*m_value));
1240             }
1241         }
1242
1243         MimeParser(ConfigParserData::AppControlInfo& data) :
1244             ElementParser(),
1245             m_properNamespace(false),
1246             m_data(data)
1247         {}
1248
1249       private:
1250         bool m_properNamespace;
1251         DPL::OptionalString m_value;
1252         ConfigParserData::AppControlInfo& m_data;
1253     };
1254
1255     struct DispositionParser : public ElementParser
1256     {
1257       public:
1258         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1259                                             const DPL::String& /*name*/)
1260         {
1261             return &IgnoringParser::Create;
1262         }
1263
1264         virtual void Accept(const Text& /*text*/)
1265         {}
1266
1267         virtual void Accept(const Element& /*element*/)
1268         {}
1269
1270         virtual void Accept(const XmlAttribute& attribute)
1271         {
1272             if (attribute.name == L"disposition") {
1273                 if (attribute.value.size() > 0) {
1274                     m_value = attribute.value;
1275                     NormalizeString(m_value);
1276                 }
1277             }
1278         }
1279
1280         virtual void Verify()
1281         {
1282             if (m_value.IsNull() || *m_value != L"inline") {
1283                 m_data.m_disposition = ConfigParserData::AppControlInfo::Disposition::WINDOW;
1284             }
1285             else {
1286                 m_data.m_disposition = ConfigParserData::AppControlInfo::Disposition::INLINE;
1287             }
1288         }
1289
1290         DispositionParser(ConfigParserData::AppControlInfo& data) :
1291             ElementParser(),
1292             m_properNamespace(false),
1293             m_data(data)
1294         {}
1295
1296       private:
1297         bool m_properNamespace;
1298         DPL::OptionalString m_value;
1299         ConfigParserData::AppControlInfo& m_data;
1300     };
1301
1302     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1303                                         const DPL::String& name)
1304     {
1305         if (name == L"src") {
1306             return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1307         } else if (name == L"operation") {
1308             return DPL::MakeDelegate(this,
1309                                      &AppControlParser::OnOperationElement);
1310         } else if (name == L"uri") {
1311             return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1312         } else if (name == L"mime") {
1313             return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1314         } else if (name == L"disposition") {
1315             return DPL::MakeDelegate(this,
1316                                      &AppControlParser::OnDispositionElement);
1317         } else {
1318             return &IgnoringParser::Create;
1319         }
1320     }
1321
1322     virtual void Accept(const XmlAttribute& /*attribute*/)
1323     {}
1324
1325     virtual void Accept(const Element& element)
1326     {
1327         LogWarning("namespace for app service = " << element.ns);
1328         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1329             ThrowMsg(Exception::ParseError,
1330                      "Wrong xml namespace for widget element");
1331         }
1332     }
1333
1334     virtual void Accept(const Text& /*text*/)
1335     {
1336         ThrowMsg(Exception::ParseError, "param element must be empty");
1337     }
1338
1339     virtual void Verify()
1340     {
1341         if (m_appControl.m_src == L"") {
1342             LogWarning("service element must have src element");
1343             return;
1344         }
1345
1346         if (m_appControl.m_operation == L"") {
1347             LogWarning("service element must have operation element");
1348             return;
1349         }
1350
1351         m_data.appControlList.push_back(m_appControl);
1352     }
1353
1354     ElementParserPtr OnSourceElement()
1355     {
1356         return ElementParserPtr(new SourceParser(m_appControl));
1357     }
1358
1359     ElementParserPtr OnOperationElement()
1360     {
1361         return ElementParserPtr(new OperationParser(m_appControl));
1362     }
1363
1364     ElementParserPtr OnUriElement()
1365     {
1366         return ElementParserPtr(new UriParser(m_appControl));
1367     }
1368
1369     ElementParserPtr OnMimeElement()
1370     {
1371         return ElementParserPtr(new MimeParser(m_appControl));
1372     }
1373
1374     ElementParserPtr OnDispositionElement()
1375     {
1376         return ElementParserPtr(new DispositionParser(m_appControl));
1377     }
1378
1379     AppControlParser(ConfigParserData& data) :
1380         ElementParser(),
1381         m_data(data),
1382         m_appControl(L"")
1383     {}
1384
1385   private:
1386     ConfigParserData& m_data;
1387     ConfigParserData::AppControlInfo m_appControl;
1388 };
1389
1390 class ApplicationParser : public ElementParser
1391 {
1392   public:
1393     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1394                                         const DPL::String& /*name*/)
1395     {
1396         return &IgnoringParser::Create;
1397     }
1398
1399     virtual void Accept(const Text& /*text*/)
1400     {
1401         if (m_properNamespace) {
1402             LogDebug("text");
1403             ThrowMsg(Exception::ParseError, "application element must be empty");
1404         }
1405     }
1406
1407     virtual void Accept(const Element& element)
1408     {
1409         if (element.ns ==
1410             ConfigurationNamespace::TizenWebAppNamespaceName)
1411         {
1412             m_properNamespace = true;
1413         }
1414         LogDebug("element");
1415     }
1416
1417     virtual void Accept(const XmlAttribute& attribute)
1418     {
1419         if (m_properNamespace) {
1420             LogDebug("attribute");
1421             if (attribute.name == L"id") {
1422                 m_id = attribute.value;
1423                 NormalizeAndTrimSpaceString(m_id);
1424             } else if (attribute.name == L"package") {
1425                 m_package = attribute.value;
1426             } else if (attribute.name == L"required_version") {
1427                 m_version = attribute.value;
1428                 NormalizeString(m_version);
1429             } else {
1430                 ThrowMsg(Exception::ParseError,
1431                          "unknown attribute '" +
1432                          DPL::ToUTF8String(attribute.name) +
1433                          "' in application element");
1434             }
1435         }
1436     }
1437
1438     virtual void Verify()
1439     {
1440         if (!m_id) {
1441             ThrowMsg(Exception::ParseError,
1442                      "application element must have id attribute");
1443         }
1444
1445         if (!!m_package) {
1446             m_data.tizenPkgId = m_package;
1447         }
1448
1449         if (!m_version) {
1450             ThrowMsg(Exception::ParseError,
1451                      "application element must have required_version attribute");
1452         }
1453
1454         //TODO check if id and version format is right
1455         m_data.tizenAppId = m_id;
1456         m_data.tizenMinVersionRequired = m_version;
1457     }
1458
1459     ApplicationParser(ConfigParserData& data) :
1460         ElementParser(),
1461         m_data(data),
1462         m_id(DPL::OptionalString::Null),
1463         m_version(DPL::OptionalString::Null),
1464         m_properNamespace(false)
1465     {}
1466
1467   private:
1468     ConfigParserData& m_data;
1469     DPL::OptionalString m_id;
1470     DPL::OptionalString m_package;
1471     DPL::OptionalString m_version;
1472     bool m_properNamespace;
1473 };
1474
1475 class SplashParser : public ElementParser
1476 {
1477   public:
1478     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1479                                         const DPL::String& /*name*/)
1480     {
1481         return &IgnoringParser::Create;
1482     }
1483
1484     virtual void Accept(const XmlAttribute& attribute)
1485     {
1486         if (attribute.name == L"src") {
1487             if (attribute.value.size() > 0) {
1488                 m_src = attribute.value;
1489             }
1490         }
1491     }
1492
1493     virtual void Accept(const Element& /*element*/)
1494     {}
1495
1496     virtual void Accept(const Text& /*text*/)
1497     {}
1498
1499     virtual void Verify()
1500     {
1501         if (m_src.IsNull()) {
1502             LogWarning(
1503                 "src attribute of splash element is mandatory - ignoring");
1504             return;
1505         }
1506
1507         m_data.splashImgSrc = m_src;
1508     }
1509
1510     SplashParser(ConfigParserData& data) :
1511         ElementParser(),
1512         m_data(data)
1513     {}
1514
1515   private:
1516     DPL::OptionalString m_src;
1517     ConfigParserData& m_data;
1518 };
1519
1520 class BackgroundParser : public ElementParser
1521 {
1522   public:
1523     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1524                                         const DPL::String& /*name*/)
1525     {
1526         return &IgnoringParser::Create;
1527     }
1528
1529     virtual void Accept(const XmlAttribute& attribute)
1530     {
1531         if (attribute.name == L"src") {
1532             if (attribute.value.size() > 0) {
1533                 m_src = attribute.value;
1534             }
1535         }
1536     }
1537
1538     virtual void Accept(const Element& /*element*/)
1539     {}
1540
1541     virtual void Accept(const Text& /*text*/)
1542     {}
1543
1544     virtual void Verify()
1545     {
1546         if (m_src.IsNull()) {
1547             LogWarning(
1548                 "src attribute of background element is mandatory - ignoring");
1549             return;
1550         }
1551
1552         m_data.backgroundPage = m_src;
1553     }
1554
1555     explicit BackgroundParser(ConfigParserData& data) :
1556         m_data(data)
1557     {}
1558
1559   private:
1560     DPL::OptionalString m_src;
1561     ConfigParserData& m_data;
1562 };
1563
1564 class PrivilegeParser : public ElementParser
1565 {
1566   public:
1567     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1568                                         const DPL::String& /*name*/)
1569     {
1570         return &IgnoringParser::Create;
1571     }
1572
1573     virtual void Accept(const Text& /*text*/)
1574     {}
1575
1576     virtual void Accept(const Element& element)
1577     {
1578         if (element.ns ==
1579             ConfigurationNamespace::TizenWebAppNamespaceName)
1580         {
1581             m_properNamespace = true;
1582         }
1583         LogDebug("element");
1584     }
1585
1586     virtual void Accept(const XmlAttribute& attribute)
1587     {
1588         if (m_properNamespace) {
1589             if (attribute.name == L"name") {
1590                 m_feature.name = attribute.value;
1591                 m_privilege.name = attribute.value;
1592             }
1593         }
1594     }
1595
1596     virtual void Verify()
1597     {
1598         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1599
1600         if (m_feature.name != L"") {
1601             if (iri.Validate()) {
1602                 if (m_data.featuresList.find(m_feature) ==
1603                     m_data.featuresList.end())
1604                 {
1605                     m_data.featuresList.insert(m_feature);
1606                 } else {
1607                     LogDebug("Ignoring feature with name" <<
1608                         DPL::ToUTF8String(m_feature.name));
1609                 }
1610             }
1611         }
1612
1613         LibIri::Wrapper iriPrivilege(
1614             DPL::ToUTF8String(m_privilege.name).c_str());
1615
1616         if (m_privilege.name != L"") {
1617             if (iriPrivilege.Validate()) {
1618                 if (m_data.privilegeList.find(m_privilege) ==
1619                     m_data.privilegeList.end())
1620                 {
1621                     m_data.privilegeList.insert(m_privilege);
1622                 } else {
1623                     LogDebug("Ignoring privilege with name" <<
1624                              DPL::ToUTF8String(m_privilege.name));
1625                 }
1626             }
1627         }
1628     }
1629
1630     PrivilegeParser(ConfigParserData& data) :
1631         ElementParser(),
1632         m_data(data),
1633         m_feature(L""),
1634         m_privilege(L""),
1635         m_properNamespace(false)
1636     {}
1637
1638   private:
1639     ConfigParserData& m_data;
1640     ConfigParserData::Feature m_feature;
1641     ConfigParserData::Privilege m_privilege;
1642     bool m_properNamespace;
1643 };
1644
1645 class CategoryParser : public ElementParser
1646 {
1647   public:
1648     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1649                                         const DPL::String& /*name*/)
1650     {
1651         return &IgnoringParser::Create;
1652     }
1653
1654     virtual void Accept(const XmlAttribute& attribute)
1655     {
1656         if (attribute.name == L"name") {
1657             if (attribute.value.size() > 0) {
1658                 m_name = attribute.value;
1659             }
1660         }
1661     }
1662
1663     virtual void Accept(const Element& /*element*/)
1664     {}
1665
1666     virtual void Accept(const Text& /*text*/)
1667     {}
1668
1669     virtual void Verify()
1670     {
1671         if (m_name.IsNull()) {
1672             LogWarning(
1673                 "name attribute of category element is mandatory - ignoring");
1674             return;
1675         }
1676
1677         if (m_data.categoryList.find(*m_name) ==
1678             m_data.categoryList.end())
1679         {
1680             m_data.categoryList.insert(*m_name);
1681         }
1682     }
1683
1684     explicit CategoryParser(ConfigParserData& data) :
1685         m_data(data)
1686     {}
1687
1688   private:
1689     DPL::OptionalString m_name;
1690     ConfigParserData& m_data;
1691 };
1692
1693 class AppWidgetParser : public ElementParser
1694 {
1695   public:
1696
1697     struct BoxLabelParser : public ElementParser
1698     {
1699         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1700                                             const DPL::String& /*name*/)
1701         {
1702             return &IgnoringParser::Create;
1703         }
1704
1705         virtual void Accept(const XmlAttribute& /*attribute*/)
1706         {}
1707
1708         virtual void Accept(const Element& element)
1709         {
1710             if (element.ns ==
1711                 ConfigurationNamespace::TizenWebAppNamespaceName)
1712             {
1713                 m_properNamespace = true;
1714             }
1715         }
1716
1717         virtual void Accept(const Text& text)
1718         {
1719             if (m_properNamespace) {
1720                 m_label = text.value;
1721             }
1722         }
1723
1724         virtual void Verify()
1725         {
1726             m_data.m_label = m_label;
1727         }
1728
1729         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1730             ElementParser(),
1731             m_properNamespace(false),
1732             m_data(data)
1733         {}
1734
1735       private:
1736         DPL::String m_label;
1737         bool m_properNamespace;
1738         ConfigParserData::LiveboxInfo& m_data;
1739     };
1740
1741     struct BoxIconParser : public ElementParser
1742     {
1743         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1744                                             const DPL::String& /*name*/)
1745         {
1746             return &IgnoringParser::Create;
1747         }
1748
1749         virtual void Accept(const XmlAttribute& attribute)
1750         {
1751             if (m_properNamespace) {
1752                 if (attribute.name == L"src") {
1753                     m_icon = attribute.value;
1754                 }
1755             }
1756         }
1757
1758         virtual void Accept(const Element& element)
1759         {
1760             if (element.ns ==
1761                 ConfigurationNamespace::TizenWebAppNamespaceName)
1762             {
1763                 m_properNamespace = true;
1764             }
1765         }
1766
1767         virtual void Accept(const Text& /*text*/)
1768         {}
1769
1770         virtual void Verify()
1771         {
1772             m_data.m_icon = m_icon;
1773         }
1774
1775         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1776             ElementParser(),
1777             m_properNamespace(false),
1778             m_data(data)
1779         {}
1780
1781       private:
1782         DPL::String m_icon;
1783         bool m_properNamespace;
1784         ConfigParserData::LiveboxInfo& m_data;
1785     };
1786
1787     struct BoxContentParser : public ElementParser
1788     {
1789         struct BoxSizeParser : public ElementParser
1790         {
1791             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1792                                                 const DPL::String& /*name*/)
1793             {
1794                 return &IgnoringParser::Create;
1795             }
1796
1797             virtual void Accept(const XmlAttribute& attribute)
1798             {
1799                 if (m_properNamespace) {
1800                     if (attribute.name == L"preview") {
1801                         m_preview = attribute.value;
1802                     }
1803                 }
1804             }
1805
1806             virtual void Accept(const Element& element)
1807             {
1808                 if (element.ns ==
1809                     ConfigurationNamespace::TizenWebAppNamespaceName)
1810                 {
1811                     m_properNamespace = true;
1812                 }
1813             }
1814
1815             virtual void Accept(const Text& text)
1816             {
1817                 if (m_properNamespace) {
1818                     m_size = text.value;
1819                 }
1820             }
1821
1822             virtual void Verify()
1823             {
1824                 std::pair<DPL::String, DPL::String> boxSize;
1825                 boxSize.first = m_size;
1826                 boxSize.second = m_preview;
1827                 m_data.m_boxSize.push_back(boxSize);
1828             }
1829
1830             explicit BoxSizeParser(
1831                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1832                 ElementParser(),
1833                 m_properNamespace(false),
1834                 m_data(data)
1835             {}
1836
1837           private:
1838             DPL::String m_size;
1839             DPL::String m_preview;
1840             bool m_properNamespace;
1841             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1842         };
1843
1844         struct PdParser : public ElementParser
1845         {
1846             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1847                                                 const DPL::String& /*name*/)
1848             {
1849                 return &IgnoringParser::Create;
1850             }
1851
1852             virtual void Accept(const XmlAttribute& attribute)
1853             {
1854                 if (m_properNamespace) {
1855                     if (attribute.name == L"src") {
1856                         m_src = attribute.value;
1857                     } else if (attribute.name == L"width") {
1858                         m_width = attribute.value;
1859                     } else if (attribute.name == L"height") {
1860                         m_height = attribute.value;
1861                     }
1862                 }
1863             }
1864
1865             virtual void Accept(const Element& element)
1866             {
1867                 if (element.ns ==
1868                     ConfigurationNamespace::TizenWebAppNamespaceName)
1869                 {
1870                     m_properNamespace = true;
1871                 }
1872             }
1873
1874             virtual void Accept(const Text& /*text*/)
1875             {}
1876
1877             virtual void Verify()
1878             {
1879                 m_data.m_pdSrc = m_src;
1880                 m_data.m_pdWidth = m_width;
1881                 m_data.m_pdHeight = m_height;
1882             }
1883
1884             explicit PdParser(
1885                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1886                 ElementParser(),
1887                 m_properNamespace(false),
1888                 m_data(data)
1889             {}
1890
1891           private:
1892             DPL::String m_src;
1893             DPL::String m_width;
1894             DPL::String m_height;
1895
1896             bool m_properNamespace;
1897             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1898         };
1899
1900         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1901                                             const DPL::String& name)
1902         {
1903             if (name == L"box-size") {
1904                 return DPL::MakeDelegate(
1905                            this,
1906                            &AppWidgetParser::BoxContentParser::
1907                                OnBoxSizeElement);
1908             } else if (name == L"pd") {
1909                 return DPL::MakeDelegate(
1910                            this,
1911                            &AppWidgetParser::BoxContentParser::
1912                                OnPdElement);
1913             } else {
1914                 ThrowMsg(Exception::ParseError,
1915                          "No element parser for name: " << name);
1916             }
1917         }
1918
1919         virtual void Accept(const XmlAttribute& attribute)
1920         {
1921             if (m_properNamespace) {
1922                 if (attribute.name == L"src") {
1923                     m_box.m_boxSrc = attribute.value;
1924                 }
1925                 if (attribute.name == L"mouse-event") {
1926                     m_box.m_boxMouseEvent = attribute.value;
1927                 }
1928                 if (attribute.name == L"touch-effect") {
1929                     m_box.m_boxTouchEffect = attribute.value;
1930                 }
1931             }
1932         }
1933
1934         virtual void Accept(const Element& element)
1935         {
1936             if (element.ns ==
1937                 ConfigurationNamespace::TizenWebAppNamespaceName)
1938             {
1939                 m_properNamespace = true;
1940             }
1941         }
1942
1943         virtual void Accept(const Text& /*text*/)
1944         {}
1945
1946         virtual void Verify()
1947         {
1948             m_data.m_boxInfo = m_box;
1949         }
1950
1951         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1952             ElementParser(),
1953             m_properNamespace(false),
1954             m_data(data)
1955         {}
1956
1957         ElementParserPtr OnBoxSizeElement()
1958         {
1959             return ElementParserPtr(new BoxSizeParser(m_box));
1960         }
1961
1962         ElementParserPtr OnPdElement()
1963         {
1964             return ElementParserPtr(new PdParser(m_box));
1965         }
1966
1967       private:
1968         DPL::String m_src;
1969         bool m_properNamespace;
1970         ConfigParserData::LiveboxInfo& m_data;
1971         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1972     };
1973
1974     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1975                                         const DPL::String& name)
1976     {
1977         if (name == L"box-label") {
1978             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
1979         } else if (name == L"box-icon") {
1980             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
1981         } else if (name == L"box-content") {
1982             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
1983         } else {
1984             return &IgnoringParser::Create;
1985         }
1986     }
1987
1988     virtual void Accept(const XmlAttribute& attribute)
1989     {
1990         if (m_properNamespace) {
1991             if (attribute.name == L"id") {
1992                 m_liveboxId = attribute.value;
1993             } else if (attribute.name == L"primary") {
1994                 m_primary = attribute.value;
1995             } else if (attribute.name == L"auto-launch") {
1996                 m_autoLaunch = attribute.value;
1997             } else if (attribute.name == L"update-period") {
1998                 m_updatePeriod = attribute.value;
1999             } else if (attribute.name == L"type") {
2000                 m_type = 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_livebox.m_liveboxId = m_liveboxId;
2020         m_livebox.m_primary = m_primary;
2021         m_livebox.m_autoLaunch = m_autoLaunch;
2022         m_livebox.m_updatePeriod = m_updatePeriod;
2023         m_livebox.m_type = m_type;
2024
2025         m_data.m_livebox.push_back(m_livebox);
2026     }
2027
2028     explicit AppWidgetParser(ConfigParserData& data) :
2029         ElementParser(),
2030         m_data(data),
2031         m_properNamespace(false)
2032     {
2033         m_livebox = ConfigParserData::LiveboxInfo();
2034     }
2035
2036     ElementParserPtr OnBoxLabelElement()
2037     {
2038         return ElementParserPtr(new BoxLabelParser(m_livebox));
2039     }
2040
2041     ElementParserPtr OnBoxIconElement()
2042     {
2043         return ElementParserPtr(new BoxIconParser(m_livebox));
2044     }
2045
2046     ElementParserPtr OnBoxContentElement()
2047     {
2048         return ElementParserPtr(new BoxContentParser(m_livebox));
2049     }
2050
2051   private:
2052     ConfigParserData& m_data;
2053     ConfigParserData::LiveboxInfo m_livebox;
2054     DPL::String m_liveboxId;
2055     DPL::String m_primary;
2056     DPL::String m_autoLaunch;
2057     DPL::String m_updatePeriod;
2058     DPL::String m_type;
2059     bool m_properNamespace;
2060 };
2061
2062 class CspParser : public ElementParser
2063 {
2064   public:
2065     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2066                                         const DPL::String& /*name*/)
2067     {
2068         return &IgnoringParser::Create;
2069     }
2070
2071     CspParser(ConfigParserData& data) :
2072         ElementParser(),
2073         m_data(data),
2074         m_properNamespace(false)
2075     {}
2076
2077     virtual void Accept(const Element& element)
2078     {
2079         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2080             m_properNamespace = true;
2081         }
2082     }
2083
2084     virtual void Accept(const XmlAttribute& /*attribute*/)
2085     {}
2086
2087     virtual void Accept(const Text& text)
2088     {
2089         if (m_properNamespace) {
2090             m_policy = text.value;
2091         }
2092     }
2093
2094     virtual void Verify()
2095     {
2096         if (!m_policy.IsNull()) {
2097             m_data.cspPolicy = *m_policy;
2098         }
2099     }
2100
2101   private:
2102     ConfigParserData& m_data;
2103     bool m_properNamespace;
2104     DPL::OptionalString m_policy;
2105 };
2106
2107 class CspReportOnlyParser : public ElementParser
2108 {
2109   public:
2110     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2111                                         const DPL::String& /*name*/)
2112     {
2113         return &IgnoringParser::Create;
2114     }
2115
2116     CspReportOnlyParser(ConfigParserData& data) :
2117         ElementParser(),
2118         m_data(data),
2119         m_properNamespace(false)
2120     {}
2121
2122     virtual void Accept(const Element& element)
2123     {
2124         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2125             m_properNamespace = true;
2126         }
2127     }
2128
2129     virtual void Accept(const XmlAttribute& /*attribute*/)
2130     {}
2131
2132     virtual void Accept(const Text& text)
2133     {
2134         if (m_properNamespace) {
2135             m_policy = text.value;
2136         }
2137     }
2138
2139     virtual void Verify()
2140     {
2141         if (!m_policy.IsNull()) {
2142             m_data.cspPolicyReportOnly = *m_policy;
2143         }
2144     }
2145
2146   private:
2147     ConfigParserData& m_data;
2148     bool m_properNamespace;
2149     DPL::OptionalString m_policy;
2150 };
2151
2152 class AccountParser : public ElementParser
2153 {
2154   public:
2155     struct AccountProviderParser : public ElementParser
2156     {
2157       public:
2158
2159           struct IconParser : public ElementParser
2160         {
2161             public:
2162                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2163                         const DPL::String& /*name*/)
2164                 {
2165                     return &IgnoringParser::Create;
2166                 }
2167
2168                 virtual void Accept(const Text& text)
2169                 {
2170                     if (text.value == L"") {
2171                         return;
2172                     }
2173                     m_value = text.value;
2174                 }
2175
2176                 virtual void Accept(const Element& /*element*/)
2177                 {}
2178
2179                 virtual void Accept(const XmlAttribute& attribute)
2180                 {
2181                     if (attribute.name == L"section") {
2182                         if (attribute.value == L"account") {
2183                             m_type = ConfigParserData::IconSectionType::DefaultIcon;
2184                         } else if (attribute.value == L"account-small") {
2185                             m_type = ConfigParserData::IconSectionType::SmallIcon;
2186                         }
2187                     }
2188                 }
2189
2190                 virtual void Verify()
2191                 {
2192                     if (m_value.IsNull() || *m_value == L"") {
2193                         return;
2194                     }
2195
2196                     std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2197                     icon.first = m_type;
2198                     icon.second = *m_value;
2199
2200                     m_data.m_iconSet.insert(icon);
2201                 }
2202
2203                 IconParser(ConfigParserData::AccountProvider& data) :
2204                     ElementParser(),
2205                     m_properNamespace(false),
2206                     m_type(ConfigParserData::DefaultIcon),
2207                     m_data(data)
2208             {}
2209
2210             private:
2211                 bool m_properNamespace;
2212                 ConfigParserData::IconSectionType m_type;
2213                 ConfigParserData::AccountProvider& m_data;
2214                 DPL::OptionalString m_value;
2215         };
2216
2217           struct DisplayNameParser : public ElementParser
2218         {
2219             public:
2220                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2221                         const DPL::String& /*name*/)
2222                 {
2223                     return &IgnoringParser::Create;
2224                 }
2225
2226                 virtual void Accept(const Text& text)
2227                 {
2228                     if (text.value == L"") {
2229                         return;
2230                     }
2231                     m_value = text.value;
2232                 }
2233
2234                 virtual void Accept(const Element& element)
2235                 {
2236                     m_lang = element.lang;
2237                     m_value= L"";
2238                 }
2239
2240                 virtual void Accept(const XmlAttribute& /*attribute*/)
2241                 {}
2242
2243                 virtual void Verify()
2244                 {
2245                     if (m_value.IsNull() || *m_value == L"") {
2246                         return;
2247                     }
2248
2249                     std::pair<DPL::String, DPL::String> name;
2250                     name.first = *m_lang;
2251                     name.second = *m_value;
2252
2253                     m_data.m_displayNameSet.insert(name);
2254                 }
2255
2256                 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2257                     ElementParser(),
2258                     m_properNamespace(false),
2259                     m_data(data)
2260             {}
2261
2262             private:
2263                 bool m_properNamespace;
2264                 DPL::OptionalString m_lang;
2265                 DPL::OptionalString m_value;
2266                 ConfigParserData::AccountProvider& m_data;
2267         };
2268
2269           struct CapabilityParser : public ElementParser
2270         {
2271             public:
2272                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2273                         const DPL::String& /*name*/)
2274                 {
2275                     return &IgnoringParser::Create;
2276                 }
2277
2278                 virtual void Accept(const Text& text)
2279                 {
2280                     if (text.value == L"") {
2281                         return;
2282                     }
2283                     m_value = text.value;
2284                 }
2285
2286                 virtual void Accept(const Element& /*element*/)
2287                 {}
2288
2289                 virtual void Accept(const XmlAttribute& /*attribute*/)
2290                 {}
2291
2292                 virtual void Verify()
2293                 {
2294                     if (m_value.IsNull() || *m_value == L"") {
2295                         return;
2296                     }
2297                     m_data.m_capabilityList.push_back(*m_value);
2298                 }
2299
2300                 CapabilityParser(ConfigParserData::AccountProvider& data) :
2301                     ElementParser(),
2302                     m_properNamespace(false),
2303                     m_data(data)
2304             {}
2305
2306             private:
2307                 bool m_properNamespace;
2308                 DPL::OptionalString m_value;
2309                 ConfigParserData::AccountProvider& m_data;
2310         };
2311           virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2312                   const DPL::String& name)
2313           {
2314               if (name == L"icon") {
2315                   return DPL::MakeDelegate(this, &AccountProviderParser::OnIconElement);
2316               } else if (name == L"display-name") {
2317                   return DPL::MakeDelegate(this,
2318                           &AccountProviderParser::OnDisplayNameElement);
2319               } else if (name == L"capability") {
2320                   return DPL::MakeDelegate(this, &AccountProviderParser::OnCapabilityElement);
2321               } else {
2322                   return &IgnoringParser::Create;
2323               }
2324           }
2325
2326           virtual void Accept(const Text& /*text*/)
2327           {}
2328
2329           virtual void Accept(const Element& /*element*/)
2330           {}
2331
2332           virtual void Accept(const XmlAttribute& attribute)
2333           {
2334               if (attribute.name == L"multiple-accounts-support") {
2335                   if (attribute.value == L"") {
2336                       return;
2337                   }
2338
2339                   if (attribute.value == L"ture") {
2340                       m_multiSupport = true;
2341                   }
2342               }
2343           }
2344
2345           virtual void Verify()
2346           {
2347               m_data.m_multiAccountSupport = m_multiSupport;
2348           }
2349
2350           ElementParserPtr OnIconElement()
2351           {
2352               return ElementParserPtr(new IconParser(m_data));
2353           }
2354
2355           ElementParserPtr OnDisplayNameElement()
2356           {
2357               return ElementParserPtr(new DisplayNameParser(m_data));
2358           }
2359
2360           ElementParserPtr OnCapabilityElement()
2361           {
2362               return ElementParserPtr(new CapabilityParser(m_data));
2363           }
2364
2365           AccountProviderParser(ConfigParserData::AccountProvider& data) :
2366               ElementParser(),
2367               m_properNamespace(false),
2368               m_multiSupport(false),
2369               m_data(data)
2370         {}
2371
2372       private:
2373           bool m_properNamespace;
2374           bool m_multiSupport;
2375           ConfigParserData::AccountProvider& m_data;
2376     };
2377
2378     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2379             const DPL::String& name)
2380     {
2381         if (name == L"account-provider") {
2382             return DPL::MakeDelegate(this, &AccountParser::OnProviderElement);
2383         } else {
2384             return &IgnoringParser::Create;
2385         }
2386     }
2387
2388     virtual void Accept(const Element& element)
2389     {
2390         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2391             m_properNamespace = true;
2392         }
2393     }
2394
2395     virtual void Accept(const XmlAttribute& /*attribute*/)
2396     {}
2397
2398     virtual void Accept(const Text& /*text*/)
2399     {}
2400
2401     virtual void Verify()
2402     {}
2403
2404     ElementParserPtr OnProviderElement()
2405     {
2406         return ElementParserPtr(new AccountProviderParser(m_account));
2407     }
2408
2409     AccountParser(ConfigParserData& data) :
2410         ElementParser(),
2411         m_data(data),
2412         m_account(data.accountProvider),
2413         m_properNamespace(false),
2414         m_multiSupport(false)
2415     {}
2416
2417   private:
2418     ConfigParserData& m_data;
2419     ConfigParserData::AccountProvider& m_account;
2420     bool m_properNamespace;
2421     bool m_multiSupport;
2422 };
2423
2424 ElementParser::ActionFunc WidgetParser::GetElementParser(
2425     const DPL::String& /*ns*/,
2426     const DPL::String&
2427     name)
2428 {
2429     FuncMap::const_iterator it = m_map.find(name);
2430     if (it != m_map.end()) {
2431         return it->second;
2432     } else {
2433         return &IgnoringParser::Create;
2434     }
2435 }
2436
2437 WidgetParser::WidgetParser(ConfigParserData& data) :
2438     m_data(data),
2439     m_textDirection(Unicode::EMPTY)
2440 {
2441     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2442     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2443     m_map[L"description"] =
2444         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2445     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2446     m_map[L"license"] =
2447         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2448     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2449     m_map[L"content"] =
2450         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2451     m_map[L"preference"] =
2452         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2453     m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement);
2454     m_map[L"setting"] =
2455         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2456     // TODO: appservice will be removed
2457     m_map[L"appservice"] = DPL::MakeDelegate(this,
2458                                              &WidgetParser::OnAppServiceElement);
2459     m_map[L"application"] = DPL::MakeDelegate(
2460             this,
2461             &WidgetParser::
2462                 OnApplicationElement);
2463     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2464     m_map[L"background"] = DPL::MakeDelegate(this,
2465                                              &WidgetParser::OnBackgroundElement);
2466     m_map[L"privilege"] = DPL::MakeDelegate(this,
2467                                             &WidgetParser::OnPrivilegeElement);
2468     m_map[L"app-control"] = DPL::MakeDelegate(
2469             this,
2470             &WidgetParser::
2471                 OnAppControlElement);
2472     m_map[L"category"] = DPL::MakeDelegate(this,
2473                                            &WidgetParser::OnCategoryElement);
2474     m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
2475 #ifdef CSP_ENABLED
2476     m_map[L"content-security-policy"] = DPL::MakeDelegate(
2477             this,
2478             &WidgetParser::
2479                 OnCspElement);
2480     m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
2481             this,
2482             &WidgetParser::
2483                 OnCspReportOnlyElement);
2484 #endif
2485     m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
2486 }
2487
2488 ElementParserPtr WidgetParser::OnNameElement()
2489 {
2490     return ElementParserPtr(new NameParser(m_textDirection, m_data));
2491 }
2492
2493 ElementParserPtr WidgetParser::OnAccessElement()
2494 {
2495     return ElementParserPtr(new AccessParser(m_data));
2496 }
2497
2498 ElementParserPtr WidgetParser::OnDescriptionElement()
2499 {
2500     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2501 }
2502
2503 ElementParserPtr WidgetParser::OnAuthorElement()
2504 {
2505     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2506 }
2507
2508 ElementParserPtr WidgetParser::OnLicenseElement()
2509 {
2510     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2511 }
2512
2513 ElementParserPtr WidgetParser::OnIconElement()
2514 {
2515     return ElementParserPtr(new IconParser(m_data));
2516 }
2517
2518 ElementParserPtr WidgetParser::OnContentElement()
2519 {
2520     return ElementParserPtr(new ContentParser(m_data));
2521 }
2522
2523 ElementParserPtr WidgetParser::OnPreferenceElement()
2524 {
2525     return ElementParserPtr(new PreferenceParser(m_data));
2526 }
2527
2528 ElementParserPtr WidgetParser::OnLinkElement()
2529 {
2530     return ElementParserPtr(new LinkParser(m_data));
2531 }
2532
2533 ElementParserPtr WidgetParser::OnSettingElement()
2534 {
2535     return ElementParserPtr(new SettingParser(m_data));
2536 }
2537
2538 ElementParserPtr WidgetParser::OnApplicationElement()
2539 {
2540     return ElementParserPtr(new ApplicationParser(m_data));
2541 }
2542
2543 ElementParserPtr WidgetParser::OnSplashElement()
2544 {
2545     return ElementParserPtr(new SplashParser(m_data));
2546 }
2547
2548 ElementParserPtr WidgetParser::OnBackgroundElement()
2549 {
2550     return ElementParserPtr(new BackgroundParser(m_data));
2551 }
2552
2553 ElementParserPtr WidgetParser::OnPrivilegeElement()
2554 {
2555     return ElementParserPtr(new PrivilegeParser(m_data));
2556 }
2557
2558 ElementParserPtr WidgetParser::OnAppServiceElement()
2559 {
2560     return ElementParserPtr(new AppServiceParser(m_data));
2561 }
2562
2563 ElementParserPtr WidgetParser::OnAppControlElement()
2564 {
2565     return ElementParserPtr(new AppControlParser(m_data));
2566 }
2567
2568 ElementParserPtr WidgetParser::OnCategoryElement()
2569 {
2570     return ElementParserPtr(new CategoryParser(m_data));
2571 }
2572
2573 ElementParserPtr WidgetParser::OnAppWidgetElement()
2574 {
2575     return ElementParserPtr(new AppWidgetParser(m_data));
2576 }
2577
2578 ElementParserPtr WidgetParser::OnCspElement()
2579 {
2580     return ElementParserPtr(new CspParser(m_data));
2581 }
2582
2583 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
2584 {
2585     return ElementParserPtr(new CspReportOnlyParser(m_data));
2586 }
2587
2588 ElementParserPtr WidgetParser::OnAccountElement()
2589 {
2590     return ElementParserPtr(new AccountParser(m_data));
2591 }
2592
2593 void WidgetParser::Accept(const Element& element)
2594 {
2595     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2596         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2597     {
2598         ThrowMsg(Exception::ParseError,
2599                  "Wrong xml namespace for widget element");
2600     }
2601 }
2602
2603 void WidgetParser::Accept(const Text& /*text*/)
2604 {
2605     ThrowMsg(Exception::ParseError, "widged element must be empty");
2606 }
2607
2608 void WidgetParser::Accept(const XmlAttribute& attribute)
2609 {
2610     if (attribute.name == L"id") {
2611         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2612         //If may important tests starts to fail this test we will have
2613         //to consider commenting this test out again.
2614         if (iri.Validate()) {
2615             m_data.widget_id = attribute.value;
2616             NormalizeString(m_data.widget_id);
2617         } else {
2618             LogWarning("Widget id validation failed: " << attribute.value);
2619         }
2620     } else if (attribute.name == L"version") {
2621         m_version = attribute.value;
2622         NormalizeString(m_version);
2623     } else if (attribute.name == L"min-version") {
2624         LogInfo("min-version attribute was found. Value: " << attribute.value);
2625         m_minVersion = attribute.value;
2626         NormalizeString(m_minVersion);
2627         m_data.minVersionRequired = m_minVersion;
2628     } else if (attribute.name == L"height") {
2629         DPL::OptionalString value = attribute.value;
2630         NormalizeString(value);
2631         std::string v = DPL::ToUTF8String(*value);
2632
2633         if (!v.empty()) {
2634             unsigned char c = v.c_str()[0];
2635             if (c >= '0' && c <= '9') {
2636                 int val = 0;
2637                 for (size_t i = 0; i < v.size(); ++i) {
2638                     c = v.c_str()[i];
2639                     if (c >= '0' && c <= '9') {
2640                         val *= 10;
2641                         val += (c - '0');
2642                     } else {
2643                         break;
2644                     }
2645                 }
2646                 m_data.height = val;
2647             }
2648         }
2649     } else if (attribute.name == L"width") {
2650         DPL::OptionalString value = attribute.value;
2651         NormalizeString(value);
2652         std::string v = DPL::ToUTF8String(*value);
2653
2654         if (!v.empty()) {
2655             unsigned char c = v.c_str()[0];
2656             if (c >= '0' && c <= '9') {
2657                 int val = 0;
2658                 for (size_t i = 0; i < v.size(); ++i) {
2659                     c = v.c_str()[i];
2660                     if (c >= '0' && c <= '9') {
2661                         val *= 10;
2662                         val += (c - '0');
2663                     } else {
2664                         break;
2665                     }
2666                 }
2667                 m_data.width = val;
2668             }
2669         }
2670     } else if (attribute.name == L"viewmodes") {
2671         DPL::Tokenize(attribute.value,
2672                       L" ",
2673                       std::inserter(m_windowModes,
2674                                     m_windowModes.end()),
2675                       true);
2676     } else if (attribute.name == L"dir") {
2677         m_textDirection = Unicode::ParseDirAttribute(attribute);
2678     } else if (L"defaultlocale" == attribute.name) {
2679         if (!m_defaultlocale) {
2680             m_defaultlocale = attribute.value;
2681             NormalizeString(m_defaultlocale);
2682             if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag(
2683                     DPL::ToUTF8String(*m_defaultlocale)))
2684             {
2685                 LogWarning("Language tag: " <<
2686                            m_defaultlocale << " is not valid");
2687                 m_defaultlocale = DPL::OptionalString::Null;
2688             } else {
2689                 LogDebug("Default Locale Found " << m_defaultlocale);
2690             }
2691         } else {
2692             LogWarning("Ignoring subsequent default locale");
2693         }
2694
2695         //Any other value consider as a namespace definition
2696     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2697         LogInfo("Namespace domain: " << attribute.name);
2698         LogInfo("Namespace value: " << attribute.value);
2699         m_nameSpaces[attribute.name] = attribute.value;
2700     } else {
2701         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2702                  ", name=" << attribute.name <<
2703                  ", value=" << attribute.value);
2704     }
2705 }
2706
2707 void WidgetParser::Verify()
2708 {
2709     FOREACH(mode, m_windowModes) {
2710         if (L"windowed" == *mode || L"floating" == *mode ||
2711             L"fullscreen" == *mode || L"maximized" == *mode ||
2712             L"minimized" == *mode)
2713         {
2714             m_data.windowModes.insert(*mode);
2715         }
2716     }
2717     if (!m_version.IsNull()) {
2718         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2719         m_data.version = m_version;
2720     }
2721     m_data.defaultlocale = m_defaultlocale;
2722     FOREACH(ns, m_nameSpaces) {
2723         m_data.nameSpaces.insert(ns->second);
2724     }
2725 }
2726