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