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