Tizen appservice 'disposition' attribute added.
[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         ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
297                                                 m_bSubDomainAccess);
298         //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
299             m_data.accessInfoSet.insert(accessInfo);
300     }
301
302     virtual void Verify()
303     {
304         switch (m_standardType) {
305         case STANDARD_TYPE_WARP:
306             VerifyWac();
307             break;
308         default:
309             LogError("Error in Access tag - unknown standard.");
310             break;
311         }
312     }
313
314     AccessParser(ConfigParserData& data) :
315         ElementParser(),
316         m_bSubDomainAccess(false),
317         m_standardType(STANDARD_TYPE_NONE),
318         m_network(false),
319         m_data(data)
320     {}
321
322     ElementParserPtr Other()
323     {
324         return ElementParserPtr(new InnerElementsParser(
325                                     ElementParserPtr(shared_from_this())));
326     }
327
328   private:
329     DPL::String m_strIRIOrigin;
330     bool m_bSubDomainAccess;
331     StandardType m_standardType;
332     bool m_network;
333     ConfigParserData& m_data;
334 };
335
336 class DescriptionParser : public ElementParser
337 {
338   public:
339     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
340                                         const DPL::String& /*name*/)
341     {
342         return DPL::MakeDelegate(this, &DescriptionParser::Other);
343     }
344
345     virtual void Accept(const Element& element)
346     {
347         m_lang = element.lang;
348         m_description = L"";
349     }
350
351     ElementParserPtr Other()
352     {
353         return ElementParserPtr(new InnerElementsParser(
354                                     std::static_pointer_cast<ElementParser>(
355                                         shared_from_this())));
356     }
357
358     virtual void Accept(const Text& text)
359     {
360         if (m_description.IsNull()) {
361             m_description = text.value;
362         } else {
363             *m_description += text.value;
364         }
365     }
366
367     virtual void Accept(const XmlAttribute& attribute)
368     {
369         if (attribute.name == L"dir") {
370             m_textDirection = Unicode::ParseDirAttribute(attribute);
371         }
372     }
373
374     virtual void Verify()
375     {
376         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
377         if (data.description.IsNull()) {
378             if (!m_description.IsNull()) {
379                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
380                                                      &*m_description);
381             }
382             data.description = m_description;
383         }
384     }
385
386     DescriptionParser(Unicode::Direction direction,
387                       ConfigParserData& data) :
388         m_data(data),
389         m_lang(),
390         m_description(),
391         m_textDirection(direction)
392     {}
393
394   private:
395     ConfigParserData& m_data;
396     DPL::String m_lang;
397     DPL::OptionalString m_description;
398     Unicode::Direction m_textDirection;
399 };
400
401 class AuthorParser : public ElementParser
402 {
403   public:
404     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
405                                         const DPL::String& /*name*/)
406     {
407         return DPL::MakeDelegate(this, &AuthorParser::Other);
408     }
409
410     AuthorParser(Unicode::Direction direction,
411                  ConfigParserData& data) :
412         m_data(data),
413         m_textDirection(direction)
414     {}
415
416     virtual void Accept(const Element& /*element*/)
417     {
418         m_authorName = L"";
419     }
420
421     virtual void Accept(const Text& text)
422     {
423         *(m_authorName) += text.value;
424     }
425
426     virtual void Accept(const XmlAttribute& attribute)
427     {
428         if (attribute.name == L"href") {
429             //Validate href IRI and ignore it if invalid
430             //See also test: ta-argMozRiC-an
431             LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
432             if (iri.Validate()) {
433                 m_authorHref = attribute.value;
434             }
435         } else if (attribute.name == L"email") {
436             m_authorEmail = attribute.value;
437         } else if (attribute.name == L"dir") {
438             m_textDirection = Unicode::ParseDirAttribute(attribute);
439         }
440     }
441
442     virtual void Verify()
443     {
444         if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) {
445             NormalizeString(m_authorName);
446             NormalizeString(m_authorHref);
447             NormalizeString(m_authorEmail);
448             if (!!m_authorName) {
449                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
450                                                      &*m_authorName);
451                 m_data.authorName = m_authorName;
452             }
453             if (!!m_authorHref) {
454                 m_data.authorHref = m_authorHref;
455             }
456             if (!!m_authorEmail) {
457                 m_data.authorEmail = m_authorEmail;
458             }
459         }
460     }
461
462     ElementParserPtr Other()
463     {
464         return ElementParserPtr(new InnerElementsParser(
465                                     std::static_pointer_cast<ElementParser>(
466                                         shared_from_this())));
467     }
468
469   private:
470     ConfigParserData& m_data;
471     DPL::OptionalString m_authorEmail;
472     DPL::OptionalString m_authorHref;
473     DPL::OptionalString m_authorName;
474     Unicode::Direction m_textDirection;
475 };
476
477 class LicenseParser : public ElementParser
478 {
479   public:
480     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
481                                         const DPL::String& /*name*/)
482     {
483         return DPL::MakeDelegate(this, &LicenseParser::Other);
484     }
485
486     LicenseParser(Unicode::Direction direction,
487                   ConfigParserData& data) :
488         m_data(data),
489         m_ignore(true),
490         m_textDirection(direction)
491     {}
492
493     virtual void Accept(const Element& element)
494     {
495         if (m_license.IsNull()) {
496             m_lang = element.lang;
497             m_license = L"";
498             m_ignore = false;
499         }
500     }
501
502     virtual void Accept(const Text& text)
503     {
504         if (!m_ignore) {
505             *m_license += text.value;
506         }
507     }
508
509     virtual void Accept(const XmlAttribute& attribute)
510     {
511         if (!m_ignore) {
512             if (attribute.name == L"href" && m_licenseHref.IsNull()) {
513                 m_licenseHref = attribute.value;
514             } else if (attribute.name == L"file" && m_licenseFile.IsNull()) {
515                 m_licenseFile = attribute.value;
516             } else if (attribute.name == L"dir") {
517                 m_textDirection = Unicode::ParseDirAttribute(attribute);
518             }
519         }
520     }
521
522     virtual void Verify()
523     {
524         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
525         if (data.license.IsNull()) {
526             if (!m_license.IsNull()) {
527                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
528                                                      &*m_license);
529             }
530             data.license = m_license;
531             data.licenseHref = m_licenseHref;
532             data.licenseFile = m_licenseFile;
533         }
534     }
535
536     ElementParserPtr Other()
537     {
538         return ElementParserPtr(new InnerElementsParser(
539                                     ElementParserPtr(shared_from_this())));
540     }
541
542   private:
543     ConfigParserData& m_data;
544     DPL::String m_lang;
545     bool m_ignore;
546
547     DPL::OptionalString m_license;
548     DPL::OptionalString m_licenseFile;
549     DPL::OptionalString m_licenseHref;
550     Unicode::Direction m_textDirection;
551 };
552
553 class IconParser : public ElementParser
554 {
555     DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
556
557   public:
558     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
559                                         const DPL::String& /*name*/)
560     {
561         return &IgnoringParser::Create;
562     }
563
564     IconParser(ConfigParserData& data) : ElementParser(),
565         m_data(data)
566     {}
567
568     virtual void Accept(const Element& /*element*/)
569     {}
570
571     virtual void Accept(const XmlAttribute& attribute)
572     {
573         if (attribute.name == L"src") {
574             if (attribute.value.size() > 0) {
575                 m_src = attribute.value;
576             }
577         } else if (attribute.name == L"width") {
578             m_width = ParseSizeAttributeValue(attribute.value);
579         } else if (attribute.name == L"height") {
580             m_height = ParseSizeAttributeValue(attribute.value);
581         }
582     }
583
584     virtual void Accept(const Text& /*text*/)
585     {
586         ThrowMsg(Exception::ParseError, "Icon element must be empty");
587     }
588
589     virtual void Verify()
590     {
591         if (m_src.IsNull()) {
592             LogWarning("src attribute of icon element is mandatory - ignoring");
593             return;
594         }
595
596         Try
597         {
598             ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
599             icon.width = m_width;
600             icon.height = m_height;
601
602             ConfigParserData::IconsList::iterator it = std::find(
603                     m_data.iconsList.begin(), m_data.iconsList.end(), icon);
604             if (it == m_data.iconsList.end()) {
605                 m_data.iconsList.push_front(icon);
606             }
607         }
608         Catch(BadSrcError)
609         {
610             LogWarning("src attribute is invalid: " << m_src);
611         }
612     }
613
614   private:
615     ConfigParserData& m_data;
616     DPL::OptionalString m_src;
617     DPL::OptionalInt m_width;
618     DPL::OptionalInt m_height;
619
620     static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
621     {
622         DPL::OptionalString normalizedValue = value;
623         NormalizeString(normalizedValue);
624         if (!(*normalizedValue).empty()) {
625             char* reterr = NULL;
626             errno = 0;
627             long int valueInt =
628                 strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
629             if (errno != 0 ||
630                 std::string(reterr) == DPL::ToUTF8String(value) ||
631                 valueInt <= 0)
632             {
633                 return DPL::OptionalInt::Null;
634             } else {
635                 return valueInt;
636             }
637         }
638         return DPL::OptionalInt::Null;
639     }
640
641     /**
642      * @brief delocalizePath removes locales folder from relative path if
643      * neccessary
644      * @param source source string
645      *
646      * @throw BadSrcError if string is bad value of src attribute
647      *
648      * @return corrected string
649      */
650     static DPL::String delocalizeSrcPath(const DPL::String & source)
651     {
652         static const DPL::String localeFolder(L"locales/");
653         static const int index = localeFolder.size();
654
655         DPL::String result = source;
656
657         if (source.substr(0, index) == localeFolder) {
658             size_t pos = result.find_first_of('/', index);
659             if (pos != std::string::npos && pos + 1 < source.size()) {
660                 result = result.substr(pos + 1, source.size());
661             } else {
662                 Throw(BadSrcError);
663             }
664         }
665         return result;
666     }
667 };
668
669 class ContentParser : public ElementParser
670 {
671   public:
672     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
673                                         const DPL::String& /*name*/)
674     {
675         return &IgnoringParser::Create;
676     }
677
678     ContentParser(ConfigParserData& data) :
679         ElementParser(),
680         m_data(data)
681     {}
682
683     virtual void Accept(const Element& /*element*/)
684     {}
685
686     virtual void Accept(const Text& /*text*/)
687     {}
688
689     virtual void Accept(const XmlAttribute& attribute)
690     {
691         DPL::String value = attribute.value;
692         NormalizeString(value);
693
694         if (attribute.name == L"src") {
695             m_src = value;
696         } else if (attribute.name == L"type") {
697             m_type = value;
698             MimeTypeUtils::MimeAttributes mimeAttributes =
699                 MimeTypeUtils::getMimeAttributes(value);
700             if (mimeAttributes.count(L"charset") > 0) {
701                 m_encoding = mimeAttributes[L"charset"];
702             }
703         } else if (attribute.name == L"encoding") {
704             if (!value.empty()) {
705                 m_encoding = value;
706             }
707         }
708     }
709
710     virtual void Verify()
711     {
712         if (m_data.startFileEncountered) {
713             LogWarning("This is not the first encountered "
714                        "'content' element - ignoring.");
715             return;
716         }
717
718         m_data.startFileEncountered = true;
719
720         //we're consciously setting startFile even if m_src is null or invalid.
721         //WidgetConfigurationManager will deal with this.
722         m_data.startFile = m_src;
723
724         if (!!m_src) {
725             m_data.startFileContentType = m_type;
726             if (!!m_encoding) {
727                 m_data.startFileEncoding = m_encoding;
728             } else {
729                 m_data.startFileEncoding = L"UTF-8";
730             }
731         }
732     }
733
734   private:
735     DPL::OptionalString m_src;
736     DPL::OptionalString m_type;
737     DPL::OptionalString m_encoding;
738     ConfigParserData& m_data;
739 };
740
741 class FeatureParser : public ElementParser
742 {
743   public:
744     struct ParamParser : public ElementParser
745     {
746         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
747                                             const DPL::String& /*name*/)
748         {
749             return &IgnoringParser::Create;
750         }
751
752         virtual void Accept(const XmlAttribute& attribute)
753         {
754             if (attribute.name == L"name") {
755                 m_name = attribute.value;
756                 NormalizeString(m_name);
757             } else if (attribute.name == L"value") {
758                 m_value = attribute.value;
759                 NormalizeString(m_value);
760             }
761         }
762
763         virtual void Accept(const Element& /*element*/)
764         {}
765
766         virtual void Accept(const Text& /*text*/)
767         {
768             ThrowMsg(Exception::ParseError, "param element must be empty");
769         }
770
771         virtual void Verify()
772         {
773             if (m_name.IsNull() || *m_name == L"") {
774                 return;
775             }
776             if (m_value.IsNull() || *m_value == L"") {
777                 return;
778             }
779
780             ConfigParserData::Param param(*m_name);
781             param.value = *m_value;
782
783             if (m_data.paramsList.find(param) == m_data.paramsList.end()) {
784                 m_data.paramsList.insert(param);
785             }
786         }
787
788         ParamParser(ConfigParserData::Feature& data) :
789             ElementParser(),
790             m_data(data)
791         {}
792
793       private:
794         DPL::OptionalString m_name;
795         DPL::OptionalString m_value;
796         ConfigParserData::Feature& m_data;
797     };
798
799     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
800                                         const DPL::String& name)
801     {
802         if (name == L"param") {
803             return DPL::MakeDelegate(this, &FeatureParser::OnParamElement);
804         } else {
805             return &IgnoringParser::Create;
806         }
807     }
808
809     virtual void Accept(const Text& /*text*/)
810     {}
811
812     virtual void Accept(const Element& /*element*/)
813     {}
814
815     virtual void Accept(const XmlAttribute& attribute)
816     {
817         if (attribute.name == L"name") {
818             m_feature.name = attribute.value;
819         } else if (attribute.name == L"required") {
820             if (attribute.value == L"false") {
821                 m_feature.required = false;
822             } else {
823                 m_feature.required = true;
824             }
825         }
826     }
827
828     virtual void Verify()
829     {
830         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
831
832         if (m_feature.name != L"") {
833             if (iri.Validate()) {
834                 if (m_data.featuresList.find(m_feature) ==
835                     m_data.featuresList.end())
836                 {
837                     m_data.featuresList.insert(m_feature);
838                 } else {
839                     LogDebug("Ignoring feature with name" <<
840                              DPL::ToUTF8String(m_feature.name));
841                 }
842             } else {
843                 if (m_feature.required) {
844                     //Throw only if required
845                     ThrowMsg(Exception::ParseError, "invalid feature IRI");
846                 }
847             }
848         }
849     }
850
851     ElementParserPtr OnParamElement()
852     {
853         return ElementParserPtr(new ParamParser(m_feature));
854     }
855
856     FeatureParser(ConfigParserData& data) :
857         ElementParser(),
858         m_data(data),
859         m_feature(L"")
860     {}
861
862   private:
863     ConfigParserData& m_data;
864     ConfigParserData::Feature m_feature;
865 };
866
867 class PreferenceParser : public ElementParser
868 {
869   public:
870     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
871                                         const DPL::String& /*name*/)
872     {
873         return &IgnoringParser::Create;
874     }
875
876     virtual void Accept(const XmlAttribute& attribute)
877     {
878         if (attribute.name == L"name") {
879             m_name = attribute.value;
880         } else if (attribute.name == L"value") {
881             m_value = attribute.value;
882         } else if (attribute.name == L"readonly") {
883             if (attribute.value == L"true") {
884                 m_required = true;
885             } else {
886                 m_required = false;
887             }
888         }
889     }
890
891     virtual void Accept(const Element& /*element*/)
892     {}
893
894     virtual void Accept(const Text& /*text*/)
895     {
896         ThrowMsg(Exception::ParseError, "param element must be empty");
897     }
898
899     virtual void Verify()
900     {
901         if (m_name.IsNull()) {
902             LogWarning("preference element must have name attribute");
903             return;
904         }
905         NormalizeString(m_name);
906         NormalizeString(m_value);
907         ConfigParserData::Preference preference(*m_name, m_required);
908         preference.value = m_value;
909         if (m_data.preferencesList.find(preference) ==
910             m_data.preferencesList.end())
911         {
912             m_data.preferencesList.insert(preference);
913         }
914     }
915
916     PreferenceParser(ConfigParserData& data) :
917         ElementParser(),
918         m_required(false),
919         m_data(data)
920     {}
921
922   private:
923     DPL::OptionalString m_name;
924     DPL::OptionalString m_value;
925     bool m_required;
926     ConfigParserData& m_data;
927 };
928
929 class LinkParser : public ElementParser
930 {
931   public:
932     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
933                                         const DPL::String& /*name*/)
934     {
935         return &DenyAllParser::Create;
936     }
937
938     virtual void Accept(const XmlAttribute& attribute)
939     {
940         if (m_properNamespace) {
941             LogDebug("attribute");
942             if (attribute.name == L"rel") {
943                 if (attribute.value != L"describedby") {
944                     ThrowMsg(Exception::ParseError,
945                              "rel attribute must have describedby value");
946                 }
947             } else if (attribute.name == L"type") {} else if (attribute.name ==
948                                                               L"href")
949             {
950                 LogDebug("here is href");
951                 m_href = attribute.value;
952             } else {
953                 ThrowMsg(Exception::ParseError,
954                          "unknown attribute '" +
955                          DPL::ToUTF8String(attribute.name) +
956                          "' in link element");
957             }
958         }
959     }
960
961     virtual void Accept(const Element& element)
962     {
963         if (element.ns ==
964             ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement)
965         {
966             m_properNamespace = true;
967         }
968         LogDebug("element");
969     }
970
971     virtual void Accept(const Text&)
972     {
973         if (m_properNamespace) {
974             LogDebug("text");
975             ThrowMsg(Exception::ParseError, "link element must be empty");
976         }
977     }
978
979     virtual void Verify()
980     {
981         if (!m_href) {
982             ThrowMsg(Exception::ParseError,
983                      "link element must have href attribute");
984         }
985
986         LibIri::Wrapper iri(DPL::ToUTF8String(*m_href).c_str());
987         if (!iri.Validate()) { // TODO: Better uri validator ?
988             ThrowMsg(Exception::ParseError,
989                      "href attribute must be a valid iri/uri/url");
990         }
991     }
992
993     LinkParser(ConfigParserData& data) :
994         ElementParser(),
995         m_properNamespace(false),
996         m_data(data),
997         m_href(DPL::OptionalString::Null)
998     {}
999
1000   private:
1001     bool m_properNamespace;
1002     ConfigParserData& m_data;
1003     DPL::OptionalString m_href;
1004 };
1005
1006 class SettingParser : public ElementParser
1007 {
1008   public:
1009     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1010                                         const DPL::String& /*name*/)
1011     {
1012         return &IgnoringParser::Create;
1013     }
1014
1015     virtual void Accept(const Text& /*text*/)
1016     {}
1017
1018     virtual void Accept(const Element& /*element*/)
1019     {}
1020
1021     virtual void Accept(const XmlAttribute& attribute)
1022     {
1023         m_setting.m_name = attribute.name;
1024         m_setting.m_value = attribute.value;
1025         m_data.settingsList.insert(m_setting);
1026     }
1027
1028     virtual void Verify()
1029     {}
1030
1031     SettingParser(ConfigParserData& data) :
1032         ElementParser(),
1033         m_data(data),
1034         m_setting(L"", L"")
1035     {}
1036
1037   private:
1038     ConfigParserData& m_data;
1039     ConfigParserData::Setting m_setting;
1040 };
1041
1042 class AppServiceParser : public ElementParser
1043 {
1044   public:
1045     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1046                                         const DPL::String& /*name*/)
1047     {
1048         return &IgnoringParser::Create;
1049     }
1050
1051     virtual void Accept(const XmlAttribute& attribute)
1052     {
1053         if (attribute.name == L"src") {
1054             m_src = attribute.value;
1055         } else if (attribute.name == L"operation") {
1056             m_operation = attribute.value;
1057         } else if (attribute.name == L"scheme") {
1058             m_scheme = attribute.value;
1059         } else if (attribute.name == L"mime") {
1060             m_mime = attribute.value;
1061         } else if (attribute.name == L"disposition") {
1062             if (attribute.value == L"inline")
1063                 m_disposition =
1064                     ConfigParserData::ServiceInfo::Disposition::INLINE;
1065         }
1066     }
1067
1068     virtual void Accept(const Element& element)
1069     {
1070         LogWarning("namespace for app service = " << element.ns);
1071         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1072             ThrowMsg(Exception::ParseError,
1073                      "Wrong xml namespace for widget element");
1074         }
1075     }
1076
1077     virtual void Accept(const Text& /*text*/)
1078     {
1079         ThrowMsg(Exception::ParseError, "param element must be empty");
1080     }
1081
1082     virtual void Verify()
1083     {
1084         if (m_src.IsNull()) {
1085             LogWarning("service element must have target attribute");
1086             return;
1087         } else if (m_operation.IsNull()) {
1088             LogWarning("service element must have operation attribute");
1089             return;
1090         }
1091         NormalizeString(m_src);
1092         NormalizeString(m_operation);
1093         NormalizeString(m_scheme);
1094         NormalizeString(m_mime);
1095
1096         // verify duplicate element
1097         DPL::String wildString(L"*/*");
1098         DPL::String nullString(L"");
1099         ConfigParserData::ServiceInfo serviceInfo(
1100             m_src.IsNull() ? nullString : *m_src,
1101             m_operation.IsNull() ? nullString : *m_operation,
1102             m_scheme.IsNull() ? nullString : *m_scheme,
1103             m_mime.IsNull() ? nullString : *m_mime,
1104             m_disposition);
1105
1106         FOREACH(iterator, m_data.appServiceList) {
1107             if (iterator->m_operation == serviceInfo.m_operation &&
1108                 // check scheme
1109                 (iterator->m_scheme == serviceInfo.m_scheme ||
1110                  // check input scheme is "*/*" case
1111                  (iterator->m_scheme == wildString &&
1112                   serviceInfo.m_scheme != nullString) ||
1113                  // check iterator scheme is "*/*" case
1114                  (serviceInfo.m_scheme == wildString &&
1115                   iterator->m_scheme != nullString)) &&
1116
1117                 (iterator->m_mime == serviceInfo.m_mime ||
1118                  // check input mime is "*/*" case
1119                  (iterator->m_mime == wildString &&
1120                   serviceInfo.m_mime != nullString) ||
1121                  // check iterator mime is "*/*" case
1122                  (serviceInfo.m_mime == wildString &&
1123                   iterator->m_mime != nullString)))
1124             {
1125                 ThrowMsg(Exception::ParseError,
1126                          "service operation is duplicated " +
1127                          DPL::ToUTF8String(*m_operation));
1128             }
1129         }
1130         m_data.appServiceList.push_back(serviceInfo);
1131     }
1132
1133     AppServiceParser(ConfigParserData& data) :
1134         ElementParser(),
1135         m_src(DPL::OptionalString::Null),
1136         m_operation(DPL::OptionalString::Null),
1137         m_scheme(DPL::OptionalString::Null),
1138         m_mime(DPL::OptionalString::Null),
1139         m_disposition(ConfigParserData::ServiceInfo::Disposition::WINDOW),
1140         m_data(data)
1141     {}
1142
1143   private:
1144     DPL::OptionalString m_src;
1145     DPL::OptionalString m_operation;
1146     DPL::OptionalString m_scheme;
1147     DPL::OptionalString m_mime;
1148     ConfigParserData::ServiceInfo::Disposition m_disposition;
1149     ConfigParserData& m_data;
1150 };
1151
1152 class AppControlParser : public ElementParser
1153 {
1154   public:
1155     struct SourceParser : public ElementParser
1156     {
1157       public:
1158         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1159                                             const DPL::String& /*name*/)
1160         {
1161             return &IgnoringParser::Create;
1162         }
1163
1164         virtual void Accept(const Text& /*text*/)
1165         {}
1166
1167         virtual void Accept(const Element& /*element*/)
1168         {}
1169
1170         virtual void Accept(const XmlAttribute& attribute)
1171         {
1172             if (attribute.name == L"name") {
1173                 if (attribute.value.size() > 0) {
1174                     m_value = attribute.value;
1175                     NormalizeString(m_value);
1176                 }
1177             }
1178         }
1179
1180         virtual void Verify()
1181         {
1182             if (m_value.IsNull() || *m_value == L"") {
1183                 return;
1184             }
1185
1186             m_data.m_src = *m_value;
1187         }
1188
1189         SourceParser(ConfigParserData::AppControlInfo& data) :
1190             ElementParser(),
1191             m_properNamespace(false),
1192             m_data(data)
1193         {}
1194
1195       private:
1196         bool m_properNamespace;
1197         DPL::OptionalString m_value;
1198         ConfigParserData::AppControlInfo& m_data;
1199     };
1200
1201     struct OperationParser : public ElementParser
1202     {
1203       public:
1204         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1205                                             const DPL::String& /*name*/)
1206         {
1207             return &IgnoringParser::Create;
1208         }
1209
1210         virtual void Accept(const Text& /*text*/)
1211         {}
1212
1213         virtual void Accept(const Element& /*element*/)
1214         {}
1215
1216         virtual void Accept(const XmlAttribute& attribute)
1217         {
1218             if (attribute.name == L"name") {
1219                 if (attribute.value.size() > 0) {
1220                     m_value = attribute.value;
1221                     NormalizeString(m_value);
1222                 }
1223             }
1224         }
1225
1226         virtual void Verify()
1227         {
1228             if (m_value.IsNull() || *m_value == L"") {
1229                 return;
1230             }
1231
1232             m_data.m_operation = *m_value;
1233         }
1234
1235         OperationParser(ConfigParserData::AppControlInfo& data) :
1236             ElementParser(),
1237             m_properNamespace(false),
1238             m_data(data)
1239         {}
1240
1241       private:
1242         bool m_properNamespace;
1243         DPL::OptionalString m_value;
1244         ConfigParserData::AppControlInfo& m_data;
1245     };
1246
1247     struct UriParser : public ElementParser
1248     {
1249       public:
1250         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1251                                             const DPL::String& /*name*/)
1252         {
1253             return &IgnoringParser::Create;
1254         }
1255
1256         virtual void Accept(const Text& /*text*/)
1257         {}
1258
1259         virtual void Accept(const Element& /*element*/)
1260         {}
1261
1262         virtual void Accept(const XmlAttribute& attribute)
1263         {
1264             if (attribute.name == L"name") {
1265                 if (attribute.value.size() > 0) {
1266                     m_value = attribute.value;
1267                     NormalizeString(m_value);
1268                 }
1269             }
1270         }
1271
1272         virtual void Verify()
1273         {
1274             if (m_value.IsNull() || *m_value == L"") {
1275                 return;
1276             }
1277
1278             DPL::String wildString(L"*/*");
1279             if ((m_data.m_uriList.find(wildString) ==
1280                  m_data.m_uriList.end())
1281                 && (m_data.m_uriList.find(*m_value) ==
1282                     m_data.m_uriList.end()))
1283             {
1284                 m_data.m_uriList.insert(*m_value);
1285             } else {
1286                 LogDebug("Ignoring uri with name" <<
1287                          DPL::ToUTF8String(*m_value));
1288             }
1289         }
1290
1291         UriParser(ConfigParserData::AppControlInfo& data) :
1292             ElementParser(),
1293             m_properNamespace(false),
1294             m_data(data)
1295         {}
1296
1297       private:
1298         bool m_properNamespace;
1299         DPL::OptionalString m_value;
1300         ConfigParserData::AppControlInfo& m_data;
1301     };
1302
1303     struct MimeParser : public ElementParser
1304     {
1305       public:
1306         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1307                                             const DPL::String& /*name*/)
1308         {
1309             return &IgnoringParser::Create;
1310         }
1311
1312         virtual void Accept(const Text& /*text*/)
1313         {}
1314
1315         virtual void Accept(const Element& /*element*/)
1316         {}
1317
1318         virtual void Accept(const XmlAttribute& attribute)
1319         {
1320             if (attribute.name == L"name") {
1321                 if (attribute.value.size() > 0) {
1322                     m_value = attribute.value;
1323                     NormalizeString(m_value);
1324                 }
1325             }
1326         }
1327
1328         virtual void Verify()
1329         {
1330             if (m_value.IsNull() || *m_value == L"") {
1331                 return;
1332             }
1333
1334             DPL::String wildString(L"*/*");
1335             if ((m_data.m_mimeList.find(wildString) ==
1336                  m_data.m_mimeList.end())
1337                 && (m_data.m_mimeList.find(*m_value) ==
1338                     m_data.m_mimeList.end()))
1339             {
1340                 m_data.m_mimeList.insert(*m_value);
1341             } else {
1342                 LogDebug("Ignoring mime with name" <<
1343                          DPL::ToUTF8String(*m_value));
1344             }
1345         }
1346
1347         MimeParser(ConfigParserData::AppControlInfo& data) :
1348             ElementParser(),
1349             m_properNamespace(false),
1350             m_data(data)
1351         {}
1352
1353       private:
1354         bool m_properNamespace;
1355         DPL::OptionalString m_value;
1356         ConfigParserData::AppControlInfo& m_data;
1357     };
1358
1359     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1360                                         const DPL::String& name)
1361     {
1362         if (name == L"src") {
1363             return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1364         } else if (name == L"operation") {
1365             return DPL::MakeDelegate(this,
1366                                      &AppControlParser::OnOperationElement);
1367         } else if (name == L"uri") {
1368             return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1369         } else if (name == L"mime") {
1370             return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1371         } else {
1372             return &IgnoringParser::Create;
1373         }
1374     }
1375
1376     virtual void Accept(const XmlAttribute& /*attribute*/)
1377     {}
1378
1379     virtual void Accept(const Element& element)
1380     {
1381         LogWarning("namespace for app service = " << element.ns);
1382         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1383             ThrowMsg(Exception::ParseError,
1384                      "Wrong xml namespace for widget element");
1385         }
1386     }
1387
1388     virtual void Accept(const Text& /*text*/)
1389     {
1390         ThrowMsg(Exception::ParseError, "param element must be empty");
1391     }
1392
1393     virtual void Verify()
1394     {
1395         if (m_appControl.m_src == L"") {
1396             LogWarning("service element must have src element");
1397             return;
1398         }
1399
1400         if (m_appControl.m_operation == L"") {
1401             LogWarning("service element must have operation element");
1402             return;
1403         }
1404
1405         FOREACH(iterator, m_data.appControlList) {
1406             if (iterator->m_src == m_appControl.m_src &&
1407                 iterator->m_operation == m_appControl.m_operation)
1408             {
1409                 ThrowMsg(Exception::ParseError,
1410                          "app control element is duplicated " +
1411                          DPL::ToUTF8String(m_appControl.m_src) + ", " +
1412                          DPL::ToUTF8String(m_appControl.m_operation));
1413             }
1414         }
1415         m_data.appControlList.push_back(m_appControl);
1416     }
1417
1418     ElementParserPtr OnSourceElement()
1419     {
1420         return ElementParserPtr(new SourceParser(m_appControl));
1421     }
1422
1423     ElementParserPtr OnOperationElement()
1424     {
1425         return ElementParserPtr(new OperationParser(m_appControl));
1426     }
1427
1428     ElementParserPtr OnUriElement()
1429     {
1430         return ElementParserPtr(new UriParser(m_appControl));
1431     }
1432
1433     ElementParserPtr OnMimeElement()
1434     {
1435         return ElementParserPtr(new MimeParser(m_appControl));
1436     }
1437
1438     AppControlParser(ConfigParserData& data) :
1439         ElementParser(),
1440         m_data(data),
1441         m_appControl(L"")
1442     {}
1443
1444   private:
1445     ConfigParserData& m_data;
1446     ConfigParserData::AppControlInfo m_appControl;
1447 };
1448
1449 class ApplicationParser : public ElementParser
1450 {
1451   public:
1452     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1453                                         const DPL::String& /*name*/)
1454     {
1455         return &IgnoringParser::Create;
1456     }
1457
1458     virtual void Accept(const Text& /*text*/)
1459     {
1460         if (m_properNamespace) {
1461             LogDebug("text");
1462             ThrowMsg(Exception::ParseError, "application element must be empty");
1463         }
1464     }
1465
1466     virtual void Accept(const Element& element)
1467     {
1468         if (element.ns ==
1469             ConfigurationNamespace::TizenWebAppNamespaceName)
1470         {
1471             m_properNamespace = true;
1472         }
1473         LogDebug("element");
1474     }
1475
1476     virtual void Accept(const XmlAttribute& attribute)
1477     {
1478         if (m_properNamespace) {
1479             LogDebug("attribute");
1480             if (attribute.name == L"id") {
1481                 m_id = attribute.value;
1482                 NormalizeAndTrimSpaceString(m_id);
1483             } else if (attribute.name == L"package") {
1484                 m_package = attribute.value;
1485             } else if (attribute.name == L"required_version") {
1486                 m_version = attribute.value;
1487                 NormalizeString(m_version);
1488             } else {
1489                 ThrowMsg(Exception::ParseError,
1490                          "unknown attribute '" +
1491                          DPL::ToUTF8String(attribute.name) +
1492                          "' in application element");
1493             }
1494         }
1495     }
1496
1497     virtual void Verify()
1498     {
1499         if (!m_id) {
1500             ThrowMsg(Exception::ParseError,
1501                      "application element must have id attribute");
1502         }
1503
1504         if (!!m_package) {
1505             m_data.tizenPkgId = m_package;
1506         }
1507
1508         if (!m_version) {
1509             ThrowMsg(Exception::ParseError,
1510                      "application element must have required_version attribute");
1511         }
1512
1513         //TODO check if id and version format is right
1514         m_data.tizenAppId = m_id;
1515         m_data.tizenMinVersionRequired = m_version;
1516     }
1517
1518     ApplicationParser(ConfigParserData& data) :
1519         ElementParser(),
1520         m_data(data),
1521         m_id(DPL::OptionalString::Null),
1522         m_version(DPL::OptionalString::Null),
1523         m_properNamespace(false)
1524     {}
1525
1526   private:
1527     ConfigParserData& m_data;
1528     DPL::OptionalString m_id;
1529     DPL::OptionalString m_package;
1530     DPL::OptionalString m_version;
1531     bool m_properNamespace;
1532 };
1533
1534 class SplashParser : public ElementParser
1535 {
1536   public:
1537     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1538                                         const DPL::String& /*name*/)
1539     {
1540         return &IgnoringParser::Create;
1541     }
1542
1543     virtual void Accept(const XmlAttribute& attribute)
1544     {
1545         if (attribute.name == L"src") {
1546             if (attribute.value.size() > 0) {
1547                 m_src = attribute.value;
1548             }
1549         }
1550     }
1551
1552     virtual void Accept(const Element& /*element*/)
1553     {}
1554
1555     virtual void Accept(const Text& /*text*/)
1556     {}
1557
1558     virtual void Verify()
1559     {
1560         if (m_src.IsNull()) {
1561             LogWarning(
1562                 "src attribute of splash element is mandatory - ignoring");
1563             return;
1564         }
1565
1566         m_data.splashImgSrc = m_src;
1567     }
1568
1569     SplashParser(ConfigParserData& data) :
1570         ElementParser(),
1571         m_data(data)
1572     {}
1573
1574   private:
1575     DPL::OptionalString m_src;
1576     ConfigParserData& m_data;
1577 };
1578
1579 class BackgroundParser : public ElementParser
1580 {
1581   public:
1582     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1583                                         const DPL::String& /*name*/)
1584     {
1585         return &IgnoringParser::Create;
1586     }
1587
1588     virtual void Accept(const XmlAttribute& attribute)
1589     {
1590         if (attribute.name == L"src") {
1591             if (attribute.value.size() > 0) {
1592                 m_src = attribute.value;
1593             }
1594         }
1595     }
1596
1597     virtual void Accept(const Element& /*element*/)
1598     {}
1599
1600     virtual void Accept(const Text& /*text*/)
1601     {}
1602
1603     virtual void Verify()
1604     {
1605         if (m_src.IsNull()) {
1606             LogWarning(
1607                 "src attribute of background element is mandatory - ignoring");
1608             return;
1609         }
1610
1611         m_data.backgroundPage = m_src;
1612     }
1613
1614     explicit BackgroundParser(ConfigParserData& data) :
1615         m_data(data)
1616     {}
1617
1618   private:
1619     DPL::OptionalString m_src;
1620     ConfigParserData& m_data;
1621 };
1622
1623 class PrivilegeParser : public ElementParser
1624 {
1625   public:
1626     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1627                                         const DPL::String& /*name*/)
1628     {
1629         return &IgnoringParser::Create;
1630     }
1631
1632     virtual void Accept(const Text& /*text*/)
1633     {}
1634
1635     virtual void Accept(const Element& element)
1636     {
1637         if (element.ns ==
1638             ConfigurationNamespace::TizenWebAppNamespaceName)
1639         {
1640             m_properNamespace = true;
1641         }
1642         LogDebug("element");
1643     }
1644
1645     virtual void Accept(const XmlAttribute& attribute)
1646     {
1647         if (m_properNamespace) {
1648             if (attribute.name == L"name") {
1649                 m_feature.name = attribute.value;
1650                 m_privilege.name = attribute.value;
1651             }
1652         }
1653         m_feature.required = false;
1654     }
1655
1656     virtual void Verify()
1657     {
1658         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1659
1660         if (m_feature.name != L"") {
1661             if (iri.Validate()) {
1662                 if (m_data.featuresList.find(m_feature) ==
1663                     m_data.featuresList.end())
1664                 {
1665                     m_data.featuresList.insert(m_feature);
1666                 } else {
1667                     LogDebug("Ignoring feature with name" <<
1668                              DPL::ToUTF8String(m_feature.name));
1669                 }
1670             }
1671         }
1672
1673         LibIri::Wrapper iriPrivilege(
1674             DPL::ToUTF8String(m_privilege.name).c_str());
1675
1676         if (m_privilege.name != L"") {
1677             if (iriPrivilege.Validate()) {
1678                 if (m_data.privilegeList.find(m_privilege) ==
1679                     m_data.privilegeList.end())
1680                 {
1681                     m_data.privilegeList.insert(m_privilege);
1682                 } else {
1683                     LogDebug("Ignoring privilege with name" <<
1684                              DPL::ToUTF8String(m_privilege.name));
1685                 }
1686             }
1687         }
1688     }
1689
1690     PrivilegeParser(ConfigParserData& data) :
1691         ElementParser(),
1692         m_data(data),
1693         m_feature(L""),
1694         m_privilege(L""),
1695         m_properNamespace(false)
1696     {}
1697
1698   private:
1699     ConfigParserData& m_data;
1700     ConfigParserData::Feature m_feature;
1701     ConfigParserData::Privilege m_privilege;
1702     bool m_properNamespace;
1703 };
1704
1705 class CategoryParser : public ElementParser
1706 {
1707   public:
1708     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1709                                         const DPL::String& /*name*/)
1710     {
1711         return &IgnoringParser::Create;
1712     }
1713
1714     virtual void Accept(const XmlAttribute& attribute)
1715     {
1716         if (attribute.name == L"name") {
1717             if (attribute.value.size() > 0) {
1718                 m_name = attribute.value;
1719             }
1720         }
1721     }
1722
1723     virtual void Accept(const Element& /*element*/)
1724     {}
1725
1726     virtual void Accept(const Text& /*text*/)
1727     {}
1728
1729     virtual void Verify()
1730     {
1731         if (m_name.IsNull()) {
1732             LogWarning(
1733                 "name attribute of category element is mandatory - ignoring");
1734             return;
1735         }
1736
1737         if (m_data.categoryList.find(*m_name) ==
1738             m_data.categoryList.end())
1739         {
1740             m_data.categoryList.insert(*m_name);
1741         }
1742     }
1743
1744     explicit CategoryParser(ConfigParserData& data) :
1745         m_data(data)
1746     {}
1747
1748   private:
1749     DPL::OptionalString m_name;
1750     ConfigParserData& m_data;
1751 };
1752
1753 class LiveboxParser : public ElementParser
1754 {
1755   public:
1756
1757     struct BoxLabelParser : public ElementParser
1758     {
1759         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1760                                             const DPL::String& /*name*/)
1761         {
1762             return &IgnoringParser::Create;
1763         }
1764
1765         virtual void Accept(const XmlAttribute& /*attribute*/)
1766         {}
1767
1768         virtual void Accept(const Element& element)
1769         {
1770             if (element.ns ==
1771                 ConfigurationNamespace::TizenWebAppNamespaceName)
1772             {
1773                 m_properNamespace = true;
1774             }
1775         }
1776
1777         virtual void Accept(const Text& text)
1778         {
1779             if (m_properNamespace) {
1780                 m_label = text.value;
1781             }
1782         }
1783
1784         virtual void Verify()
1785         {
1786             m_data.m_label = m_label;
1787         }
1788
1789         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1790             ElementParser(),
1791             m_properNamespace(false),
1792             m_data(data)
1793         {}
1794
1795       private:
1796         DPL::String m_label;
1797         bool m_properNamespace;
1798         ConfigParserData::LiveboxInfo& m_data;
1799     };
1800
1801     struct BoxIconParser : public ElementParser
1802     {
1803         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1804                                             const DPL::String& /*name*/)
1805         {
1806             return &IgnoringParser::Create;
1807         }
1808
1809         virtual void Accept(const XmlAttribute& attribute)
1810         {
1811             if (m_properNamespace) {
1812                 if (attribute.name == L"src") {
1813                     m_icon = attribute.value;
1814                 }
1815             }
1816         }
1817
1818         virtual void Accept(const Element& element)
1819         {
1820             if (element.ns ==
1821                 ConfigurationNamespace::TizenWebAppNamespaceName)
1822             {
1823                 m_properNamespace = true;
1824             }
1825         }
1826
1827         virtual void Accept(const Text& /*text*/)
1828         {}
1829
1830         virtual void Verify()
1831         {
1832             m_data.m_icon = m_icon;
1833         }
1834
1835         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1836             ElementParser(),
1837             m_properNamespace(false),
1838             m_data(data)
1839         {}
1840
1841       private:
1842         DPL::String m_icon;
1843         bool m_properNamespace;
1844         ConfigParserData::LiveboxInfo& m_data;
1845     };
1846
1847     struct BoxContentParser : public ElementParser
1848     {
1849         struct BoxSizeParser : public ElementParser
1850         {
1851             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1852                                                 const DPL::String& /*name*/)
1853             {
1854                 return &IgnoringParser::Create;
1855             }
1856
1857             virtual void Accept(const XmlAttribute& attribute)
1858             {
1859                 if (m_properNamespace) {
1860                     if (attribute.name == L"preview") {
1861                         m_preview = attribute.value;
1862                     }
1863                 }
1864             }
1865
1866             virtual void Accept(const Element& element)
1867             {
1868                 if (element.ns ==
1869                     ConfigurationNamespace::TizenWebAppNamespaceName)
1870                 {
1871                     m_properNamespace = true;
1872                 }
1873             }
1874
1875             virtual void Accept(const Text& text)
1876             {
1877                 if (m_properNamespace) {
1878                     m_size = text.value;
1879                 }
1880             }
1881
1882             virtual void Verify()
1883             {
1884                 std::pair<DPL::String, DPL::String> boxSize;
1885                 boxSize.first = m_size;
1886                 boxSize.second = m_preview;
1887                 m_data.m_boxSize.push_back(boxSize);
1888             }
1889
1890             explicit BoxSizeParser(
1891                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1892                 ElementParser(),
1893                 m_properNamespace(false),
1894                 m_data(data)
1895             {}
1896
1897           private:
1898             DPL::String m_size;
1899             DPL::String m_preview;
1900             bool m_properNamespace;
1901             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1902         };
1903
1904         struct PdParser : public ElementParser
1905         {
1906             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1907                                                 const DPL::String& /*name*/)
1908             {
1909                 return &IgnoringParser::Create;
1910             }
1911
1912             virtual void Accept(const XmlAttribute& attribute)
1913             {
1914                 if (m_properNamespace) {
1915                     if (attribute.name == L"src") {
1916                         m_src = attribute.value;
1917                     } else if (attribute.name == L"width") {
1918                         m_width = attribute.value;
1919                     } else if (attribute.name == L"height") {
1920                         m_height = attribute.value;
1921                     }
1922                 }
1923             }
1924
1925             virtual void Accept(const Element& element)
1926             {
1927                 if (element.ns ==
1928                     ConfigurationNamespace::TizenWebAppNamespaceName)
1929                 {
1930                     m_properNamespace = true;
1931                 }
1932             }
1933
1934             virtual void Accept(const Text& /*text*/)
1935             {}
1936
1937             virtual void Verify()
1938             {
1939                 m_data.m_pdSrc = m_src;
1940                 m_data.m_pdWidth = m_width;
1941                 m_data.m_pdHeight = m_height;
1942             }
1943
1944             explicit PdParser(
1945                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1946                 ElementParser(),
1947                 m_properNamespace(false),
1948                 m_data(data)
1949             {}
1950
1951           private:
1952             DPL::String m_src;
1953             DPL::String m_width;
1954             DPL::String m_height;
1955
1956             bool m_properNamespace;
1957             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1958         };
1959
1960         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1961                                             const DPL::String& name)
1962         {
1963             if (name == L"box-size") {
1964                 return DPL::MakeDelegate(
1965                            this,
1966                            &LiveboxParser::BoxContentParser::
1967                                OnBoxSizeElement);
1968             } else if (name == L"pd") {
1969                 return DPL::MakeDelegate(
1970                            this,
1971                            &LiveboxParser::BoxContentParser::
1972                                OnPdElement);
1973             } else {
1974                 ThrowMsg(Exception::ParseError,
1975                          "No element parser for name: " << name);
1976             }
1977         }
1978
1979         virtual void Accept(const XmlAttribute& attribute)
1980         {
1981             if (m_properNamespace) {
1982                 if (attribute.name == L"src") {
1983                     m_box.m_boxSrc = attribute.value;
1984                 }
1985                 if (attribute.name == L"mouse-event") {
1986                     m_box.m_boxMouseEvent = attribute.value;
1987                 }
1988             }
1989         }
1990
1991         virtual void Accept(const Element& element)
1992         {
1993             if (element.ns ==
1994                 ConfigurationNamespace::TizenWebAppNamespaceName)
1995             {
1996                 m_properNamespace = true;
1997             }
1998         }
1999
2000         virtual void Accept(const Text& /*text*/)
2001         {}
2002
2003         virtual void Verify()
2004         {
2005             m_data.m_boxInfo = m_box;
2006         }
2007
2008         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
2009             ElementParser(),
2010             m_properNamespace(false),
2011             m_data(data)
2012         {}
2013
2014         ElementParserPtr OnBoxSizeElement()
2015         {
2016             return ElementParserPtr(new BoxSizeParser(m_box));
2017         }
2018
2019         ElementParserPtr OnPdElement()
2020         {
2021             return ElementParserPtr(new PdParser(m_box));
2022         }
2023
2024       private:
2025         DPL::String m_src;
2026         bool m_properNamespace;
2027         ConfigParserData::LiveboxInfo& m_data;
2028         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
2029     };
2030
2031     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2032                                         const DPL::String& name)
2033     {
2034         if (name == L"box-label") {
2035             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxLabelElement);
2036         } else if (name == L"box-icon") {
2037             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxIconElement);
2038         } else if (name == L"box-content") {
2039             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxContentElement);
2040         } else {
2041             return &IgnoringParser::Create;
2042         }
2043     }
2044
2045     virtual void Accept(const XmlAttribute& attribute)
2046     {
2047         if (m_properNamespace) {
2048             if (attribute.name == L"id") {
2049                 m_liveboxId = attribute.value;
2050             } else if (attribute.name == L"primary") {
2051                 m_primary = attribute.value;
2052             } else if (attribute.name == L"auto-launch") {
2053                 m_autoLaunch = attribute.value;
2054             } else if (attribute.name == L"update-period") {
2055                 m_updatePeriod = attribute.value;
2056             } else if (attribute.name == L"type") {
2057                 m_type = attribute.value;
2058             }
2059         }
2060     }
2061
2062     virtual void Accept(const Element& element)
2063     {
2064         if (element.ns ==
2065             ConfigurationNamespace::TizenWebAppNamespaceName)
2066         {
2067             m_properNamespace = true;
2068         }
2069     }
2070
2071     virtual void Accept(const Text& /*text*/)
2072     {}
2073
2074     virtual void Verify()
2075     {
2076         m_livebox.m_liveboxId = m_liveboxId;
2077         m_livebox.m_primary = m_primary;
2078         m_livebox.m_autoLaunch = m_autoLaunch;
2079         m_livebox.m_updatePeriod = m_updatePeriod;
2080         m_livebox.m_type = m_type;
2081
2082         m_data.m_livebox.push_back(m_livebox);
2083     }
2084
2085     explicit LiveboxParser(ConfigParserData& data) :
2086         ElementParser(),
2087         m_data(data),
2088         m_properNamespace(false)
2089     {
2090         m_livebox = ConfigParserData::LiveboxInfo();
2091     }
2092
2093     ElementParserPtr OnBoxLabelElement()
2094     {
2095         return ElementParserPtr(new BoxLabelParser(m_livebox));
2096     }
2097
2098     ElementParserPtr OnBoxIconElement()
2099     {
2100         return ElementParserPtr(new BoxIconParser(m_livebox));
2101     }
2102
2103     ElementParserPtr OnBoxContentElement()
2104     {
2105         return ElementParserPtr(new BoxContentParser(m_livebox));
2106     }
2107
2108   private:
2109     ConfigParserData& m_data;
2110     ConfigParserData::LiveboxInfo m_livebox;
2111     DPL::String m_liveboxId;
2112     DPL::String m_primary;
2113     DPL::String m_autoLaunch;
2114     DPL::String m_updatePeriod;
2115     DPL::String m_type;
2116     bool m_properNamespace;
2117 };
2118
2119 class CspParser : public ElementParser
2120 {
2121   public:
2122     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2123                                         const DPL::String& /*name*/)
2124     {
2125         return &IgnoringParser::Create;
2126     }
2127
2128     CspParser(ConfigParserData& data) :
2129         ElementParser(),
2130         m_data(data),
2131         m_properNamespace(false)
2132     {}
2133
2134     virtual void Accept(const Element& element)
2135     {
2136         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2137             m_properNamespace = true;
2138         }
2139     }
2140
2141     virtual void Accept(const XmlAttribute& /*attribute*/)
2142     {}
2143
2144     virtual void Accept(const Text& text)
2145     {
2146         if (m_properNamespace) {
2147             m_policy = text.value;
2148         }
2149     }
2150
2151     virtual void Verify()
2152     {
2153         if (!m_policy.IsNull()) {
2154             m_data.cspPolicy = *m_policy;
2155         }
2156     }
2157
2158   private:
2159     ConfigParserData& m_data;
2160     bool m_properNamespace;
2161     DPL::OptionalString m_policy;
2162 };
2163
2164 ElementParser::ActionFunc WidgetParser::GetElementParser(
2165     const DPL::String& /*ns*/,
2166     const DPL::String&
2167     name)
2168 {
2169     FuncMap::const_iterator it = m_map.find(name);
2170     if (it != m_map.end()) {
2171         return it->second;
2172     } else {
2173         return &IgnoringParser::Create;
2174     }
2175 }
2176
2177 WidgetParser::WidgetParser(ConfigParserData& data) :
2178     m_data(data),
2179     m_textDirection(Unicode::EMPTY)
2180 {
2181     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2182     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2183     m_map[L"description"] =
2184         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2185     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2186     m_map[L"license"] =
2187         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2188     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2189     m_map[L"content"] =
2190         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2191     m_map[L"feature"] =
2192         DPL::MakeDelegate(this, &WidgetParser::OnFeatureElement);
2193     m_map[L"preference"] =
2194         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2195     m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement);
2196     m_map[L"setting"] =
2197         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2198     // TODO: appservice will be removed
2199     m_map[L"appservice"] = DPL::MakeDelegate(this,
2200                                              &WidgetParser::OnAppServiceElement);
2201     m_map[L"application"] = DPL::MakeDelegate(
2202             this,
2203             &WidgetParser::
2204                 OnApplicationElement);
2205     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2206     m_map[L"background"] = DPL::MakeDelegate(this,
2207                                              &WidgetParser::OnBackgroundElement);
2208     m_map[L"privilege"] = DPL::MakeDelegate(this,
2209                                             &WidgetParser::OnPrivilegeElement);
2210     m_map[L"app-control"] = DPL::MakeDelegate(
2211             this,
2212             &WidgetParser::
2213                 OnAppControlElement);
2214     m_map[L"category"] = DPL::MakeDelegate(this,
2215                                            &WidgetParser::OnCategoryElement);
2216     m_map[L"livebox"] = DPL::MakeDelegate(this, &WidgetParser::OnLiveboxElement);
2217 #ifdef CSP_ENABLED
2218     m_map[L"Content-Security-Policy"] = DPL::MakeDelegate(
2219             this,
2220             &WidgetParser::
2221                 OnCspElement);
2222 #endif
2223 }
2224
2225 ElementParserPtr WidgetParser::OnNameElement()
2226 {
2227     return ElementParserPtr(new NameParser(m_textDirection, m_data));
2228 }
2229
2230 ElementParserPtr WidgetParser::OnAccessElement()
2231 {
2232     return ElementParserPtr(new AccessParser(m_data));
2233 }
2234
2235 ElementParserPtr WidgetParser::OnDescriptionElement()
2236 {
2237     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2238 }
2239
2240 ElementParserPtr WidgetParser::OnAuthorElement()
2241 {
2242     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2243 }
2244
2245 ElementParserPtr WidgetParser::OnLicenseElement()
2246 {
2247     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2248 }
2249
2250 ElementParserPtr WidgetParser::OnIconElement()
2251 {
2252     return ElementParserPtr(new IconParser(m_data));
2253 }
2254
2255 ElementParserPtr WidgetParser::OnContentElement()
2256 {
2257     return ElementParserPtr(new ContentParser(m_data));
2258 }
2259
2260 ElementParserPtr WidgetParser::OnFeatureElement()
2261 {
2262     return ElementParserPtr(new FeatureParser(m_data));
2263 }
2264
2265 ElementParserPtr WidgetParser::OnPreferenceElement()
2266 {
2267     return ElementParserPtr(new PreferenceParser(m_data));
2268 }
2269
2270 ElementParserPtr WidgetParser::OnLinkElement()
2271 {
2272     return ElementParserPtr(new LinkParser(m_data));
2273 }
2274
2275 ElementParserPtr WidgetParser::OnSettingElement()
2276 {
2277     return ElementParserPtr(new SettingParser(m_data));
2278 }
2279
2280 ElementParserPtr WidgetParser::OnApplicationElement()
2281 {
2282     return ElementParserPtr(new ApplicationParser(m_data));
2283 }
2284
2285 ElementParserPtr WidgetParser::OnSplashElement()
2286 {
2287     return ElementParserPtr(new SplashParser(m_data));
2288 }
2289
2290 ElementParserPtr WidgetParser::OnBackgroundElement()
2291 {
2292     return ElementParserPtr(new BackgroundParser(m_data));
2293 }
2294
2295 ElementParserPtr WidgetParser::OnPrivilegeElement()
2296 {
2297     return ElementParserPtr(new PrivilegeParser(m_data));
2298 }
2299
2300 ElementParserPtr WidgetParser::OnAppServiceElement()
2301 {
2302     return ElementParserPtr(new AppServiceParser(m_data));
2303 }
2304
2305 ElementParserPtr WidgetParser::OnAppControlElement()
2306 {
2307     return ElementParserPtr(new AppControlParser(m_data));
2308 }
2309
2310 ElementParserPtr WidgetParser::OnCategoryElement()
2311 {
2312     return ElementParserPtr(new CategoryParser(m_data));
2313 }
2314
2315 ElementParserPtr WidgetParser::OnLiveboxElement()
2316 {
2317     return ElementParserPtr(new LiveboxParser(m_data));
2318 }
2319
2320 ElementParserPtr WidgetParser::OnCspElement()
2321 {
2322     return ElementParserPtr(new CspParser(m_data));
2323 }
2324
2325 void WidgetParser::Accept(const Element& element)
2326 {
2327     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2328         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2329     {
2330         ThrowMsg(Exception::ParseError,
2331                  "Wrong xml namespace for widget element");
2332     }
2333 }
2334
2335 void WidgetParser::Accept(const Text& /*text*/)
2336 {
2337     ThrowMsg(Exception::ParseError, "widged element must be empty");
2338 }
2339
2340 void WidgetParser::Accept(const XmlAttribute& attribute)
2341 {
2342     if (attribute.name == L"id") {
2343         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2344         //If may important tests starts to fail this test we will have
2345         //to consider commenting this test out again.
2346         if (iri.Validate()) {
2347             m_data.widget_id = attribute.value;
2348             NormalizeString(m_data.widget_id);
2349         } else {
2350             LogWarning("Widget id validation failed: " << attribute.value);
2351         }
2352     } else if (attribute.name == L"version") {
2353         m_version = attribute.value;
2354         NormalizeString(m_version);
2355     } else if (attribute.name == L"min-version") {
2356         LogInfo("min-version attribute was found. Value: " << attribute.value);
2357         m_minVersion = attribute.value;
2358         NormalizeString(m_minVersion);
2359         m_data.minVersionRequired = m_minVersion;
2360     } else if (attribute.name == L"height") {
2361         DPL::OptionalString value = attribute.value;
2362         NormalizeString(value);
2363         std::string v = DPL::ToUTF8String(*value);
2364
2365         if (!v.empty()) {
2366             unsigned char c = v.c_str()[0];
2367             if (c >= '0' && c <= '9') {
2368                 int val = 0;
2369                 for (size_t i = 0; i < v.size(); ++i) {
2370                     c = v.c_str()[i];
2371                     if (c >= '0' && c <= '9') {
2372                         val *= 10;
2373                         val += (c - '0');
2374                     } else {
2375                         break;
2376                     }
2377                 }
2378                 m_data.height = val;
2379             }
2380         }
2381     } else if (attribute.name == L"width") {
2382         DPL::OptionalString value = attribute.value;
2383         NormalizeString(value);
2384         std::string v = DPL::ToUTF8String(*value);
2385
2386         if (!v.empty()) {
2387             unsigned char c = v.c_str()[0];
2388             if (c >= '0' && c <= '9') {
2389                 int val = 0;
2390                 for (size_t i = 0; i < v.size(); ++i) {
2391                     c = v.c_str()[i];
2392                     if (c >= '0' && c <= '9') {
2393                         val *= 10;
2394                         val += (c - '0');
2395                     } else {
2396                         break;
2397                     }
2398                 }
2399                 m_data.width = val;
2400             }
2401         }
2402     } else if (attribute.name == L"viewmodes") {
2403         DPL::Tokenize(attribute.value,
2404                       L" ",
2405                       std::inserter(m_windowModes,
2406                                     m_windowModes.end()),
2407                       true);
2408     } else if (attribute.name == L"dir") {
2409         m_textDirection = Unicode::ParseDirAttribute(attribute);
2410     } else if (L"defaultlocale" == attribute.name) {
2411         if (!m_defaultlocale) {
2412             m_defaultlocale = attribute.value;
2413             NormalizeString(m_defaultlocale);
2414             if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag(
2415                     DPL::ToUTF8String(*m_defaultlocale)))
2416             {
2417                 LogWarning("Language tag: " <<
2418                            m_defaultlocale << " is not valid");
2419                 m_defaultlocale = DPL::OptionalString::Null;
2420             } else {
2421                 LogDebug("Default Locale Found " << m_defaultlocale);
2422             }
2423         } else {
2424             LogWarning("Ignoring subsequent default locale");
2425         }
2426
2427         //Any other value consider as a namespace definition
2428     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2429         LogInfo("Namespace domain: " << attribute.name);
2430         LogInfo("Namespace value: " << attribute.value);
2431         m_nameSpaces[attribute.name] = attribute.value;
2432     } else {
2433         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2434                  ", name=" << attribute.name <<
2435                  ", value=" << attribute.value);
2436     }
2437 }
2438
2439 void WidgetParser::Verify()
2440 {
2441     FOREACH(mode, m_windowModes) {
2442         if (L"windowed" == *mode || L"floating" == *mode ||
2443             L"fullscreen" == *mode || L"maximized" == *mode ||
2444             L"minimized" == *mode)
2445         {
2446             m_data.windowModes.insert(*mode);
2447         }
2448     }
2449     if (!m_version.IsNull()) {
2450         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2451         m_data.version = m_version;
2452     }
2453     m_data.defaultlocale = m_defaultlocale;
2454     FOREACH(ns, m_nameSpaces) {
2455         m_data.nameSpaces.insert(ns->second);
2456     }
2457 }
2458