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