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