[Release] wrt-installer_0.1.56
[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 <dpl/scoped_ptr.h>
41 #include <pcrecpp.h>
42 #include <algorithm>
43 #include <string>
44 #include <cstdio>
45 #include <cerrno>
46
47 using namespace WrtDB;
48
49 namespace Unicode {
50 static const DPL::String UTF_LRE = L"\x0202a";
51 static const DPL::String UTF_LRO = L"\x0202d";
52 static const DPL::String UTF_RLE = L"\x0202b";
53 static const DPL::String UTF_RLO = L"\x0202e";
54 static const DPL::String UTF_PDF = L"\x0202c";
55
56 Direction ParseDirAttribute(const XmlAttribute& attribute)
57 {
58     Assert(L"dir" == attribute.name);
59     if (L"ltr" == attribute.value) {
60         return LRE;
61     } else if (L"rtl" == attribute.value) {
62         return RLE;
63     } else if (L"lro" == attribute.value) {
64         return LRO;
65     } else if (L"rlo" == attribute.value) {
66         return RLO;
67     } else {
68         LogWarning("dir attribute has wrong value:" << attribute.value);
69         return EMPTY;
70     }
71 }
72
73 void UpdateTextWithDirectionMark(Direction direction,
74                                  DPL::String* text)
75 {
76     Assert(text);
77     switch (direction) {
78     case RLO:
79         *text = UTF_RLO + *text + UTF_PDF;
80         break;
81     case RLE:
82         *text = UTF_RLE + *text + UTF_PDF;
83         break;
84     case LRE:
85         *text = UTF_LRE + *text + UTF_PDF;
86         break;
87     case LRO:
88         *text = UTF_LRO + *text + UTF_PDF;
89         break;
90     case EMPTY:
91         break;
92     default:
93         Assert(false);
94         break;
95     }
96 }
97 } // namespace Unicode
98
99 class InnerElementsParser : public ElementParser
100 {
101   public:
102     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
103                                         const DPL::String& /*name*/)
104     {
105         return DPL::MakeDelegate(this, &InnerElementsParser::Other);
106     }
107
108     virtual void Accept(const Element& /*element*/)
109     {}
110
111     virtual void Accept(const Text& text)
112     {
113         if (m_text.IsNull()) {
114             m_text = text;
115         } else {
116             m_text->value += text.value;
117         }
118     }
119
120     virtual void Accept(const XmlAttribute& attribute)
121     {
122         if (attribute.name == L"dir") {
123             m_textDirection = Unicode::ParseDirAttribute(attribute);
124         }
125     }
126
127     virtual void Verify()
128     {
129         if (!m_text.IsNull()) {
130             Unicode::UpdateTextWithDirectionMark(m_textDirection,
131                                                  &m_text->value);
132             m_parentParser->Accept(*m_text);
133         }
134     }
135
136     InnerElementsParser(ElementParserPtr parent) :
137         m_parentParser(parent),
138         m_textDirection(Unicode::EMPTY)
139     {}
140
141     ElementParserPtr Other()
142     {
143         return ElementParserPtr(new InnerElementsParser(
144                                     std::static_pointer_cast<ElementParser>(
145                                         shared_from_this())));
146     }
147
148   private:
149     DPL::Optional<Text> m_text;
150     ElementParserPtr m_parentParser;
151     Unicode::Direction m_textDirection;
152 };
153
154 class NameParser : public ElementParser
155 {
156   public:
157     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
158                                         const DPL::String& /*name*/)
159     {
160         return DPL::MakeDelegate(this, &NameParser::Other);
161     }
162
163     virtual void Accept(const Element& element)
164     {
165         m_lang = element.lang;
166         m_name = L"";
167     }
168
169     virtual void Accept(const Text& text)
170     {
171         if (m_name.IsNull()) {
172             m_name = text.value;
173         } else {
174             *m_name += text.value;
175         }
176     }
177
178     virtual void Accept(const XmlAttribute& attribute)
179     {
180         if (attribute.name == L"short") {
181             if (m_shortName.IsNull()) {
182                 m_shortName = attribute.value;
183             }
184         } else if (attribute.name == L"dir") {
185             m_textDirection = Unicode::ParseDirAttribute(attribute);
186         }
187     }
188
189     virtual void Verify()
190     {
191         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
192         if (data.name.IsNull()) {
193             NormalizeString(m_name);
194             NormalizeString(m_shortName);
195             if (!m_name.IsNull()) {
196                 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
197             }
198             data.name = m_name;
199             if (!m_shortName.IsNull()) {
200                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
201                                                      &*m_shortName);
202             }
203             data.shortName = m_shortName;
204         }
205     }
206
207     NameParser(Unicode::Direction direction,
208                ConfigParserData& data) :
209         m_data(data),
210         m_textDirection(direction)
211     {}
212
213     ElementParserPtr Other()
214     {
215         return ElementParserPtr(new InnerElementsParser(
216                                     std::static_pointer_cast<ElementParser>(
217                                         shared_from_this())));
218     }
219
220   private:
221     ConfigParserData& m_data;
222     DPL::OptionalString m_name;
223     DPL::OptionalString m_shortName;
224     DPL::OptionalString m_dir;
225     DPL::String m_lang;
226     Unicode::Direction m_textDirection;
227 };
228
229 class AccessParser : public ElementParser
230 {
231   public:
232     enum StandardType
233     {
234         STANDARD_TYPE_NONE,
235         STANDARD_TYPE_WARP
236     };
237
238     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
239                                         const DPL::String& /*name*/)
240     {
241         return DPL::MakeDelegate(this, &AccessParser::Other);
242     }
243
244     virtual void Accept(const Element& element)
245     {
246         // for tizen web apps WARP should be used
247         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
248             element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
249         {
250             m_standardType = STANDARD_TYPE_WARP;
251         }
252     }
253
254     virtual void Accept(const Text& /*text*/)
255     {}
256
257     void AcceptWac(const XmlAttribute& attribute)
258     {
259         if (attribute.name == L"origin") {
260             m_strIRIOrigin = attribute.value;
261             NormalizeString(m_strIRIOrigin);
262         } else if (attribute.name == L"subdomains") {
263             DPL::String normalizedValue = attribute.value;
264             NormalizeString(normalizedValue);
265
266             if (normalizedValue == L"true") {
267                 m_bSubDomainAccess = true;
268             } else if (normalizedValue == L"false") {
269                 m_bSubDomainAccess = false;
270             }
271         }
272     }
273
274     virtual void Accept(const XmlAttribute& attribute)
275     {
276         switch (m_standardType) {
277         case STANDARD_TYPE_WARP:
278             AcceptWac(attribute);
279             break;
280         default:
281             LogError("Error in Access tag - unknown standard.");
282             break;
283         }
284     }
285
286     void VerifyWac()
287     {
288         WarpIRI iri;
289         iri.set(m_strIRIOrigin, false);
290
291         if (!iri.isAccessDefinition()) {
292             LogWarning("Access list element: " <<
293                        m_strIRIOrigin <<
294                        " is not acceptable by WARP" <<
295                        "standard and will be ignored!");
296             return;
297         }
298
299         if(m_strIRIOrigin == L"*") //wildcard match means yes for subdomains
300         {
301             m_bSubDomainAccess = true;
302         }
303
304         ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
305                                                 m_bSubDomainAccess);
306         //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
307         m_data.accessInfoSet.insert(accessInfo);
308     }
309
310     virtual void Verify()
311     {
312         switch (m_standardType) {
313         case STANDARD_TYPE_WARP:
314             VerifyWac();
315             break;
316         default:
317             LogError("Error in Access tag - unknown standard.");
318             break;
319         }
320     }
321
322     AccessParser(ConfigParserData& data) :
323         ElementParser(),
324         m_bSubDomainAccess(false),
325         m_standardType(STANDARD_TYPE_NONE),
326         m_network(false),
327         m_data(data)
328     {}
329
330     ElementParserPtr Other()
331     {
332         return ElementParserPtr(new InnerElementsParser(
333                                     ElementParserPtr(shared_from_this())));
334     }
335
336   private:
337     DPL::String m_strIRIOrigin;
338     bool m_bSubDomainAccess;
339     StandardType m_standardType;
340     bool m_network;
341     ConfigParserData& m_data;
342 };
343
344 class DescriptionParser : public ElementParser
345 {
346   public:
347     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
348                                         const DPL::String& /*name*/)
349     {
350         return DPL::MakeDelegate(this, &DescriptionParser::Other);
351     }
352
353     virtual void Accept(const Element& element)
354     {
355         m_lang = element.lang;
356         m_description = L"";
357     }
358
359     ElementParserPtr Other()
360     {
361         return ElementParserPtr(new InnerElementsParser(
362                                     std::static_pointer_cast<ElementParser>(
363                                         shared_from_this())));
364     }
365
366     virtual void Accept(const Text& text)
367     {
368         if (m_description.IsNull()) {
369             m_description = text.value;
370         } else {
371             *m_description += text.value;
372         }
373     }
374
375     virtual void Accept(const XmlAttribute& attribute)
376     {
377         if (attribute.name == L"dir") {
378             m_textDirection = Unicode::ParseDirAttribute(attribute);
379         }
380     }
381
382     virtual void Verify()
383     {
384         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
385         if (data.description.IsNull()) {
386             if (!m_description.IsNull()) {
387                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
388                                                      &*m_description);
389             }
390             data.description = m_description;
391         }
392     }
393
394     DescriptionParser(Unicode::Direction direction,
395                       ConfigParserData& data) :
396         m_data(data),
397         m_lang(),
398         m_description(),
399         m_textDirection(direction)
400     {}
401
402   private:
403     ConfigParserData& m_data;
404     DPL::String m_lang;
405     DPL::OptionalString m_description;
406     Unicode::Direction m_textDirection;
407 };
408
409 class AuthorParser : public ElementParser
410 {
411   public:
412     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
413                                         const DPL::String& /*name*/)
414     {
415         return DPL::MakeDelegate(this, &AuthorParser::Other);
416     }
417
418     AuthorParser(Unicode::Direction direction,
419                  ConfigParserData& data) :
420         m_data(data),
421         m_textDirection(direction)
422     {}
423
424     virtual void Accept(const Element& /*element*/)
425     {
426         m_authorName = L"";
427     }
428
429     virtual void Accept(const Text& text)
430     {
431         *(m_authorName) += text.value;
432     }
433
434     virtual void Accept(const XmlAttribute& attribute)
435     {
436         if (attribute.name == L"href") {
437             //Validate href IRI and ignore it if invalid
438             //See also test: ta-argMozRiC-an
439             LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
440             if (iri.Validate()) {
441                 m_authorHref = attribute.value;
442             }
443         } else if (attribute.name == L"email") {
444             m_authorEmail = attribute.value;
445         } else if (attribute.name == L"dir") {
446             m_textDirection = Unicode::ParseDirAttribute(attribute);
447         }
448     }
449
450     virtual void Verify()
451     {
452         if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) {
453             NormalizeString(m_authorName);
454             NormalizeString(m_authorHref);
455             NormalizeString(m_authorEmail);
456             if (!!m_authorName) {
457                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
458                                                      &*m_authorName);
459                 m_data.authorName = m_authorName;
460             }
461             if (!!m_authorHref) {
462                 m_data.authorHref = m_authorHref;
463             }
464             if (!!m_authorEmail) {
465                 m_data.authorEmail = m_authorEmail;
466             }
467         }
468     }
469
470     ElementParserPtr Other()
471     {
472         return ElementParserPtr(new InnerElementsParser(
473                                     std::static_pointer_cast<ElementParser>(
474                                         shared_from_this())));
475     }
476
477   private:
478     ConfigParserData& m_data;
479     DPL::OptionalString m_authorEmail;
480     DPL::OptionalString m_authorHref;
481     DPL::OptionalString m_authorName;
482     Unicode::Direction m_textDirection;
483 };
484
485 class LicenseParser : public ElementParser
486 {
487   public:
488     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
489                                         const DPL::String& /*name*/)
490     {
491         return DPL::MakeDelegate(this, &LicenseParser::Other);
492     }
493
494     LicenseParser(Unicode::Direction direction,
495                   ConfigParserData& data) :
496         m_data(data),
497         m_ignore(true),
498         m_textDirection(direction)
499     {}
500
501     virtual void Accept(const Element& element)
502     {
503         if (m_license.IsNull()) {
504             m_lang = element.lang;
505             m_license = L"";
506             m_ignore = false;
507         }
508     }
509
510     virtual void Accept(const Text& text)
511     {
512         if (!m_ignore) {
513             *m_license += text.value;
514         }
515     }
516
517     virtual void Accept(const XmlAttribute& attribute)
518     {
519         if (!m_ignore) {
520             if (attribute.name == L"href" && m_licenseHref.IsNull()) {
521                 m_licenseHref = attribute.value;
522             } else if (attribute.name == L"file" && m_licenseFile.IsNull()) {
523                 m_licenseFile = attribute.value;
524             } else if (attribute.name == L"dir") {
525                 m_textDirection = Unicode::ParseDirAttribute(attribute);
526             }
527         }
528     }
529
530     virtual void Verify()
531     {
532         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
533         if (data.license.IsNull()) {
534             if (!m_license.IsNull()) {
535                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
536                                                      &*m_license);
537             }
538             data.license = m_license;
539             data.licenseHref = m_licenseHref;
540             data.licenseFile = m_licenseFile;
541         }
542     }
543
544     ElementParserPtr Other()
545     {
546         return ElementParserPtr(new InnerElementsParser(
547                                     ElementParserPtr(shared_from_this())));
548     }
549
550   private:
551     ConfigParserData& m_data;
552     DPL::String m_lang;
553     bool m_ignore;
554
555     DPL::OptionalString m_license;
556     DPL::OptionalString m_licenseFile;
557     DPL::OptionalString m_licenseHref;
558     Unicode::Direction m_textDirection;
559 };
560
561 class IconParser : public ElementParser
562 {
563     DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
564
565   public:
566     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
567                                         const DPL::String& /*name*/)
568     {
569         return &IgnoringParser::Create;
570     }
571
572     IconParser(ConfigParserData& data) : ElementParser(),
573         m_data(data)
574     {}
575
576     virtual void Accept(const Element& /*element*/)
577     {}
578
579     virtual void Accept(const XmlAttribute& attribute)
580     {
581         if (attribute.name == L"src") {
582             if (attribute.value.size() > 0) {
583                 m_src = attribute.value;
584             }
585         } else if (attribute.name == L"width") {
586             m_width = ParseSizeAttributeValue(attribute.value);
587         } else if (attribute.name == L"height") {
588             m_height = ParseSizeAttributeValue(attribute.value);
589         }
590     }
591
592     virtual void Accept(const Text& /*text*/)
593     {
594         ThrowMsg(Exception::ParseError, "Icon element must be empty");
595     }
596
597     virtual void Verify()
598     {
599         if (m_src.IsNull()) {
600             LogWarning("src attribute of icon element is mandatory - ignoring");
601             return;
602         }
603
604         Try
605         {
606             ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
607             icon.width = m_width;
608             icon.height = m_height;
609
610             ConfigParserData::IconsList::iterator it = std::find(
611                     m_data.iconsList.begin(), m_data.iconsList.end(), icon);
612             if (it == m_data.iconsList.end()) {
613                 m_data.iconsList.push_front(icon);
614             }
615         }
616         Catch(BadSrcError)
617         {
618             LogWarning("src attribute is invalid: " << m_src);
619         }
620     }
621
622   private:
623     ConfigParserData& m_data;
624     DPL::OptionalString m_src;
625     DPL::OptionalInt m_width;
626     DPL::OptionalInt m_height;
627
628     static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
629     {
630         DPL::OptionalString normalizedValue = value;
631         NormalizeString(normalizedValue);
632         if (!(*normalizedValue).empty()) {
633             char* reterr = NULL;
634             errno = 0;
635             long int valueInt =
636                 strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
637             if (errno != 0 ||
638                 std::string(reterr) == DPL::ToUTF8String(value) ||
639                 valueInt <= 0)
640             {
641                 return DPL::OptionalInt::Null;
642             } else {
643                 return valueInt;
644             }
645         }
646         return DPL::OptionalInt::Null;
647     }
648
649     /**
650      * @brief delocalizePath removes locales folder from relative path if
651      * neccessary
652      * @param source source string
653      *
654      * @throw BadSrcError if string is bad value of src attribute
655      *
656      * @return corrected string
657      */
658     static DPL::String delocalizeSrcPath(const DPL::String & source)
659     {
660         static const DPL::String localeFolder(L"locales/");
661         static const int index = localeFolder.size();
662
663         DPL::String result = source;
664
665         if (source.substr(0, index) == localeFolder) {
666             size_t pos = result.find_first_of('/', index);
667             if (pos != std::string::npos && pos + 1 < source.size()) {
668                 result = result.substr(pos + 1, source.size());
669             } else {
670                 Throw(BadSrcError);
671             }
672         }
673         return result;
674     }
675 };
676
677 class ContentParser : public ElementParser
678 {
679   public:
680     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
681                                         const DPL::String& /*name*/)
682     {
683         return &IgnoringParser::Create;
684     }
685
686     ContentParser(ConfigParserData& data) :
687         ElementParser(),
688         m_data(data)
689     {}
690
691     virtual void Accept(const Element& /*element*/)
692     {}
693
694     virtual void Accept(const Text& /*text*/)
695     {}
696
697     virtual void Accept(const XmlAttribute& attribute)
698     {
699         DPL::String value = attribute.value;
700         NormalizeString(value);
701
702         if (attribute.name == L"src") {
703             m_src = value;
704         } else if (attribute.name == L"type") {
705             m_type = value;
706             MimeTypeUtils::MimeAttributes mimeAttributes =
707                 MimeTypeUtils::getMimeAttributes(value);
708             if ((mimeAttributes.count(L"charset") > 0) && m_encoding.IsNull())
709             {
710                 m_encoding = mimeAttributes[L"charset"];
711             }
712         } else if (attribute.name == L"encoding") {
713             if (!value.empty()) {
714                 m_encoding = value;
715             }
716         }
717     }
718
719     virtual void Verify()
720     {
721         if (m_data.startFileEncountered) {
722             LogWarning("This is not the first encountered "
723                        "'content' element - ignoring.");
724             return;
725         }
726
727         m_data.startFileEncountered = true;
728
729         //we're consciously setting startFile even if m_src is null or invalid.
730         //WidgetConfigurationManager will deal with this.
731         m_data.startFile = m_src;
732
733         if (!!m_src) {
734             m_data.startFileContentType = m_type;
735             if (!!m_encoding) {
736                 m_data.startFileEncoding = m_encoding;
737             } else {
738                 m_data.startFileEncoding = L"UTF-8";
739             }
740         }
741     }
742
743   private:
744     DPL::OptionalString m_src;
745     DPL::OptionalString m_type;
746     DPL::OptionalString m_encoding;
747     ConfigParserData& m_data;
748 };
749
750 class PreferenceParser : public ElementParser
751 {
752   public:
753     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
754                                         const DPL::String& /*name*/)
755     {
756         return &IgnoringParser::Create;
757     }
758
759     virtual void Accept(const XmlAttribute& attribute)
760     {
761         if (attribute.name == L"name") {
762             m_name = attribute.value;
763         } else if (attribute.name == L"value") {
764             m_value = attribute.value;
765         } else if (attribute.name == L"readonly") {
766             if (attribute.value == L"true") {
767                 m_required = true;
768             } else {
769                 m_required = false;
770             }
771         }
772     }
773
774     virtual void Accept(const Element& /*element*/)
775     {}
776
777     virtual void Accept(const Text& /*text*/)
778     {
779         ThrowMsg(Exception::ParseError, "param element must be empty");
780     }
781
782     virtual void Verify()
783     {
784         if (m_name.IsNull()) {
785             LogWarning("preference element must have name attribute");
786             return;
787         }
788         NormalizeString(m_name);
789         NormalizeString(m_value);
790         ConfigParserData::Preference preference(*m_name, m_required);
791         preference.value = m_value;
792         if (m_data.preferencesList.find(preference) ==
793             m_data.preferencesList.end())
794         {
795             m_data.preferencesList.insert(preference);
796         }
797     }
798
799     PreferenceParser(ConfigParserData& data) :
800         ElementParser(),
801         m_required(false),
802         m_data(data)
803     {}
804
805   private:
806     DPL::OptionalString m_name;
807     DPL::OptionalString m_value;
808     bool m_required;
809     ConfigParserData& m_data;
810 };
811
812 class LinkParser : public ElementParser
813 {
814   public:
815     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
816                                         const DPL::String& /*name*/)
817     {
818         return &DenyAllParser::Create;
819     }
820
821     virtual void Accept(const XmlAttribute& attribute)
822     {
823         if (m_properNamespace) {
824             LogDebug("attribute");
825             if (attribute.name == L"rel") {
826                 if (attribute.value != L"describedby") {
827                     ThrowMsg(Exception::ParseError,
828                              "rel attribute must have describedby value");
829                 }
830             } else if (attribute.name == L"type") {} else if (attribute.name ==
831                                                               L"href")
832             {
833                 LogDebug("here is href");
834                 m_href = attribute.value;
835             } else {
836                 ThrowMsg(Exception::ParseError,
837                          "unknown attribute '" +
838                          DPL::ToUTF8String(attribute.name) +
839                          "' in link element");
840             }
841         }
842     }
843
844     virtual void Accept(const Element& element)
845     {
846         if (element.ns ==
847             ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement)
848         {
849             m_properNamespace = true;
850         }
851         LogDebug("element");
852     }
853
854     virtual void Accept(const Text&)
855     {
856         if (m_properNamespace) {
857             LogDebug("text");
858             ThrowMsg(Exception::ParseError, "link element must be empty");
859         }
860     }
861
862     virtual void Verify()
863     {
864         if (!m_href) {
865             ThrowMsg(Exception::ParseError,
866                      "link element must have href attribute");
867         }
868
869         LibIri::Wrapper iri(DPL::ToUTF8String(*m_href).c_str());
870         if (!iri.Validate()) { // TODO: Better uri validator ?
871             ThrowMsg(Exception::ParseError,
872                      "href attribute must be a valid iri/uri/url");
873         }
874     }
875
876     LinkParser(ConfigParserData& data) :
877         ElementParser(),
878         m_properNamespace(false),
879         m_data(data),
880         m_href(DPL::OptionalString::Null)
881     {}
882
883   private:
884     bool m_properNamespace;
885     ConfigParserData& m_data;
886     DPL::OptionalString m_href;
887 };
888
889 class SettingParser : public ElementParser
890 {
891   public:
892     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
893                                         const DPL::String& /*name*/)
894     {
895         return &IgnoringParser::Create;
896     }
897
898     virtual void Accept(const Text& /*text*/)
899     {}
900
901     virtual void Accept(const Element& /*element*/)
902     {}
903
904     virtual void Accept(const XmlAttribute& attribute)
905     {
906         m_setting.m_name = attribute.name;
907         m_setting.m_value = attribute.value;
908         m_data.settingsList.insert(m_setting);
909     }
910
911     virtual void Verify()
912     {}
913
914     SettingParser(ConfigParserData& data) :
915         ElementParser(),
916         m_data(data),
917         m_setting(L"", L"")
918     {}
919
920   private:
921     ConfigParserData& m_data;
922     ConfigParserData::Setting m_setting;
923 };
924
925 class AppControlParser : public ElementParser
926 {
927   public:
928     struct SourceParser : public ElementParser
929     {
930       public:
931         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
932                                             const DPL::String& /*name*/)
933         {
934             return &IgnoringParser::Create;
935         }
936
937         virtual void Accept(const Text& /*text*/)
938         {}
939
940         virtual void Accept(const Element& /*element*/)
941         {}
942
943         virtual void Accept(const XmlAttribute& attribute)
944         {
945             if (attribute.name == L"name") {
946                 if (attribute.value.size() > 0) {
947                     m_value = attribute.value;
948                     NormalizeString(m_value);
949                 }
950             }
951         }
952
953         virtual void Verify()
954         {
955             if (m_value.IsNull() || *m_value == L"") {
956                 return;
957             }
958
959             m_data.m_src = *m_value;
960         }
961
962         SourceParser(ConfigParserData::AppControlInfo& data) :
963             ElementParser(),
964             m_properNamespace(false),
965             m_data(data)
966         {}
967
968       private:
969         bool m_properNamespace;
970         DPL::OptionalString m_value;
971         ConfigParserData::AppControlInfo& m_data;
972     };
973
974     struct OperationParser : public ElementParser
975     {
976       public:
977         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
978                                             const DPL::String& /*name*/)
979         {
980             return &IgnoringParser::Create;
981         }
982
983         virtual void Accept(const Text& /*text*/)
984         {}
985
986         virtual void Accept(const Element& /*element*/)
987         {}
988
989         virtual void Accept(const XmlAttribute& attribute)
990         {
991             if (attribute.name == L"name") {
992                 if (attribute.value.size() > 0) {
993                     m_value = attribute.value;
994                     NormalizeString(m_value);
995                 }
996             }
997         }
998
999         virtual void Verify()
1000         {
1001             if (m_value.IsNull() || *m_value == L"") {
1002                 return;
1003             }
1004
1005             m_data.m_operation = *m_value;
1006         }
1007
1008         OperationParser(ConfigParserData::AppControlInfo& data) :
1009             ElementParser(),
1010             m_properNamespace(false),
1011             m_data(data)
1012         {}
1013
1014       private:
1015         bool m_properNamespace;
1016         DPL::OptionalString m_value;
1017         ConfigParserData::AppControlInfo& m_data;
1018     };
1019
1020     struct UriParser : public ElementParser
1021     {
1022       public:
1023         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1024                                             const DPL::String& /*name*/)
1025         {
1026             return &IgnoringParser::Create;
1027         }
1028
1029         virtual void Accept(const Text& /*text*/)
1030         {}
1031
1032         virtual void Accept(const Element& /*element*/)
1033         {}
1034
1035         virtual void Accept(const XmlAttribute& attribute)
1036         {
1037             if (attribute.name == L"name") {
1038                 if (attribute.value.size() > 0) {
1039                     m_value = attribute.value;
1040                     NormalizeString(m_value);
1041                 }
1042             }
1043         }
1044
1045         virtual void Verify()
1046         {
1047             // exception
1048             DPL::String ignoreUri(L"file");
1049
1050             if (!m_value.IsNull() && *m_value == ignoreUri)
1051             {
1052                 LogInfo("exception : '" << *m_value << "' scheme will be ignored.");
1053                 m_value = DPL::OptionalString::Null;
1054             }
1055
1056             if (m_value.IsNull() || *m_value == L"") {
1057                 return;
1058             }
1059
1060             DPL::String wildString(L"*/*");
1061             if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
1062                 && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
1063             {
1064                 m_data.m_uriList.insert(*m_value);
1065             } else {
1066                 LogDebug("Ignoring uri with name" <<
1067                          DPL::ToUTF8String(*m_value));
1068             }
1069         }
1070
1071         UriParser(ConfigParserData::AppControlInfo& data) :
1072             ElementParser(),
1073             m_properNamespace(false),
1074             m_data(data)
1075         {}
1076
1077       private:
1078         bool m_properNamespace;
1079         DPL::OptionalString m_value;
1080         ConfigParserData::AppControlInfo& m_data;
1081     };
1082
1083     struct MimeParser : public ElementParser
1084     {
1085       public:
1086         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1087                                             const DPL::String& /*name*/)
1088         {
1089             return &IgnoringParser::Create;
1090         }
1091
1092         virtual void Accept(const Text& /*text*/)
1093         {}
1094
1095         virtual void Accept(const Element& /*element*/)
1096         {}
1097
1098         virtual void Accept(const XmlAttribute& attribute)
1099         {
1100             if (attribute.name == L"name") {
1101                 if (attribute.value.size() > 0) {
1102                     m_value = attribute.value;
1103                     NormalizeString(m_value);
1104                 }
1105             }
1106         }
1107
1108         virtual void Verify()
1109         {
1110             if (m_value.IsNull() || *m_value == L"") {
1111                 return;
1112             }
1113
1114             DPL::String wildString(L"*/*");
1115             if ((m_data.m_mimeList.find(wildString) ==
1116                  m_data.m_mimeList.end())
1117                 && (m_data.m_mimeList.find(*m_value) ==
1118                     m_data.m_mimeList.end()))
1119             {
1120                 m_data.m_mimeList.insert(*m_value);
1121             } else {
1122                 LogDebug("Ignoring mime with name" <<
1123                          DPL::ToUTF8String(*m_value));
1124             }
1125         }
1126
1127         MimeParser(ConfigParserData::AppControlInfo& data) :
1128             ElementParser(),
1129             m_properNamespace(false),
1130             m_data(data)
1131         {}
1132
1133       private:
1134         bool m_properNamespace;
1135         DPL::OptionalString m_value;
1136         ConfigParserData::AppControlInfo& m_data;
1137     };
1138
1139     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1140                                         const DPL::String& name)
1141     {
1142         if (name == L"src") {
1143             return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1144         } else if (name == L"operation") {
1145             return DPL::MakeDelegate(this,
1146                                      &AppControlParser::OnOperationElement);
1147         } else if (name == L"uri") {
1148             return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1149         } else if (name == L"mime") {
1150             return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1151         } else {
1152             return &IgnoringParser::Create;
1153         }
1154     }
1155
1156     virtual void Accept(const XmlAttribute& /*attribute*/)
1157     {}
1158
1159     virtual void Accept(const Element& element)
1160     {
1161         LogWarning("namespace for app service = " << element.ns);
1162         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1163             ThrowMsg(Exception::ParseError,
1164                      "Wrong xml namespace for widget element");
1165         }
1166     }
1167
1168     virtual void Accept(const Text& /*text*/)
1169     {
1170         ThrowMsg(Exception::ParseError, "param element must be empty");
1171     }
1172
1173     virtual void Verify()
1174     {
1175         if (m_appControl.m_src == L"") {
1176             LogWarning("service element must have src element");
1177             return;
1178         }
1179
1180         if (m_appControl.m_operation == L"") {
1181             LogWarning("service element must have operation element");
1182             return;
1183         }
1184
1185         m_data.appControlList.push_back(m_appControl);
1186     }
1187
1188     ElementParserPtr OnSourceElement()
1189     {
1190         return ElementParserPtr(new SourceParser(m_appControl));
1191     }
1192
1193     ElementParserPtr OnOperationElement()
1194     {
1195         return ElementParserPtr(new OperationParser(m_appControl));
1196     }
1197
1198     ElementParserPtr OnUriElement()
1199     {
1200         return ElementParserPtr(new UriParser(m_appControl));
1201     }
1202
1203     ElementParserPtr OnMimeElement()
1204     {
1205         return ElementParserPtr(new MimeParser(m_appControl));
1206     }
1207
1208     AppControlParser(ConfigParserData& data) :
1209         ElementParser(),
1210         m_data(data),
1211         m_appControl(L"")
1212     {}
1213
1214   private:
1215     ConfigParserData& m_data;
1216     ConfigParserData::AppControlInfo m_appControl;
1217 };
1218
1219 class ApplicationParser : public ElementParser
1220 {
1221   public:
1222     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1223                                         const DPL::String& /*name*/)
1224     {
1225         return &IgnoringParser::Create;
1226     }
1227
1228     virtual void Accept(const Text& /*text*/)
1229     {
1230         if (m_properNamespace) {
1231             LogDebug("text");
1232             ThrowMsg(Exception::ParseError, "application element must be empty");
1233         }
1234     }
1235
1236     virtual void Accept(const Element& element)
1237     {
1238         if (element.ns ==
1239             ConfigurationNamespace::TizenWebAppNamespaceName)
1240         {
1241             m_properNamespace = true;
1242         }
1243         LogDebug("element");
1244     }
1245
1246     virtual void Accept(const XmlAttribute& attribute)
1247     {
1248         if (m_properNamespace) {
1249             LogDebug("attribute");
1250             if (attribute.name == L"id") {
1251                 m_id = attribute.value;
1252                 NormalizeAndTrimSpaceString(m_id);
1253             } else if (attribute.name == L"package") {
1254                 m_package = attribute.value;
1255             } else if (attribute.name == L"required_version") {
1256                 m_version = attribute.value;
1257                 NormalizeString(m_version);
1258             } else {
1259                 ThrowMsg(Exception::ParseError,
1260                          "unknown attribute '" +
1261                          DPL::ToUTF8String(attribute.name) +
1262                          "' in application element");
1263             }
1264         }
1265     }
1266
1267     virtual void Verify()
1268     {
1269         VerifyIdAndPackage();
1270         VerifyVersion();
1271     }
1272
1273     ApplicationParser(ConfigParserData& data) :
1274         ElementParser(),
1275         m_data(data),
1276         m_id(DPL::OptionalString::Null),
1277         m_version(DPL::OptionalString::Null),
1278         m_properNamespace(false)
1279     {}
1280
1281   private:
1282     void VerifyIdAndPackage()
1283     {
1284         if (!m_package)
1285         {
1286             ThrowMsg(Exception::ParseError,
1287                      "application element must have package attribute");
1288         }
1289         else
1290         {
1291             pcrecpp::RE re(REGEXP_PACKAGE);
1292             if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
1293             {
1294                 ThrowMsg(Exception::ParseError,
1295                          "invalid format of package attribute");
1296             }
1297         }
1298
1299         if (!m_id) {
1300             ThrowMsg(Exception::ParseError,
1301                      "application element must have id attribute");
1302         }
1303         else
1304         {
1305             std::string package;
1306             pcrecpp::RE re(REGEXP_ID);
1307             if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
1308             {
1309                 ThrowMsg(Exception::ParseError,
1310                          "invalid format of id attribute");
1311             }
1312             if (package != DPL::ToUTF8String(*m_package))
1313             {
1314                 ThrowMsg(Exception::ParseError,
1315                          "invalid package prefix in id attribute");
1316             }
1317         }
1318
1319         m_data.tizenAppId = m_id;
1320         m_data.tizenPkgId = m_package;
1321     }
1322
1323     void VerifyVersion()
1324     {
1325         if (!m_version)
1326         {
1327             ThrowMsg(Exception::ParseError,
1328                      "application element must have required_version attribute");
1329         }
1330         else
1331         {
1332             pcrecpp::RE re(REGEXP_VERSION);
1333             if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
1334             {
1335                 ThrowMsg(Exception::ParseError,
1336                          "invalid format of version attribute");
1337             }
1338         }
1339
1340         m_data.tizenMinVersionRequired = m_version;
1341     }
1342
1343     static const char* const REGEXP_PACKAGE;
1344     static const char* const REGEXP_ID;
1345     static const char* const REGEXP_VERSION;
1346
1347     ConfigParserData& m_data;
1348     DPL::OptionalString m_id;
1349     DPL::OptionalString m_package;
1350     DPL::OptionalString m_version;
1351     bool m_properNamespace;
1352 };
1353
1354 const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
1355 const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
1356 const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)?";
1357
1358 class SplashParser : public ElementParser
1359 {
1360   public:
1361     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1362                                         const DPL::String& /*name*/)
1363     {
1364         return &IgnoringParser::Create;
1365     }
1366
1367     virtual void Accept(const XmlAttribute& attribute)
1368     {
1369         if (attribute.name == L"src") {
1370             if (attribute.value.size() > 0) {
1371                 m_src = attribute.value;
1372             }
1373         }
1374     }
1375
1376     virtual void Accept(const Element& /*element*/)
1377     {}
1378
1379     virtual void Accept(const Text& /*text*/)
1380     {}
1381
1382     virtual void Verify()
1383     {
1384         if (m_src.IsNull()) {
1385             LogWarning(
1386                 "src attribute of splash element is mandatory - ignoring");
1387             return;
1388         }
1389
1390         m_data.splashImgSrc = m_src;
1391     }
1392
1393     SplashParser(ConfigParserData& data) :
1394         ElementParser(),
1395         m_data(data)
1396     {}
1397
1398   private:
1399     DPL::OptionalString m_src;
1400     ConfigParserData& m_data;
1401 };
1402
1403 class BackgroundParser : public ElementParser
1404 {
1405   public:
1406     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1407                                         const DPL::String& /*name*/)
1408     {
1409         return &IgnoringParser::Create;
1410     }
1411
1412     virtual void Accept(const XmlAttribute& attribute)
1413     {
1414         if (attribute.name == L"src") {
1415             if (attribute.value.size() > 0) {
1416                 m_src = attribute.value;
1417             }
1418         }
1419     }
1420
1421     virtual void Accept(const Element& /*element*/)
1422     {}
1423
1424     virtual void Accept(const Text& /*text*/)
1425     {}
1426
1427     virtual void Verify()
1428     {
1429         if (m_src.IsNull()) {
1430             LogWarning(
1431                 "src attribute of background element is mandatory - ignoring");
1432             return;
1433         }
1434
1435         m_data.backgroundPage = m_src;
1436     }
1437
1438     explicit BackgroundParser(ConfigParserData& data) :
1439         m_data(data)
1440     {}
1441
1442   private:
1443     DPL::OptionalString m_src;
1444     ConfigParserData& m_data;
1445 };
1446
1447 class PrivilegeParser : public ElementParser
1448 {
1449   public:
1450     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1451                                         const DPL::String& /*name*/)
1452     {
1453         return &IgnoringParser::Create;
1454     }
1455
1456     virtual void Accept(const Text& /*text*/)
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             if (attribute.name == L"name") {
1473                 m_feature.name = attribute.value;
1474                 m_privilege.name = attribute.value;
1475             }
1476         }
1477     }
1478
1479     virtual void Verify()
1480     {
1481         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1482
1483         if (m_feature.name != L"") {
1484             if (iri.Validate()) {
1485                 if (m_data.featuresList.find(m_feature) ==
1486                     m_data.featuresList.end())
1487                 {
1488                     m_data.featuresList.insert(m_feature);
1489                 } else {
1490                     LogDebug("Ignoring feature with name" <<
1491                         DPL::ToUTF8String(m_feature.name));
1492                 }
1493             }
1494         }
1495
1496         LibIri::Wrapper iriPrivilege(
1497             DPL::ToUTF8String(m_privilege.name).c_str());
1498
1499         if (m_privilege.name != L"") {
1500             if (iriPrivilege.Validate()) {
1501                 if (m_data.privilegeList.find(m_privilege) ==
1502                     m_data.privilegeList.end())
1503                 {
1504                     m_data.privilegeList.insert(m_privilege);
1505                 } else {
1506                     LogDebug("Ignoring privilege with name" <<
1507                              DPL::ToUTF8String(m_privilege.name));
1508                 }
1509             }
1510         }
1511     }
1512
1513     PrivilegeParser(ConfigParserData& data) :
1514         ElementParser(),
1515         m_data(data),
1516         m_feature(L""),
1517         m_privilege(L""),
1518         m_properNamespace(false)
1519     {}
1520
1521   private:
1522     ConfigParserData& m_data;
1523     ConfigParserData::Feature m_feature;
1524     ConfigParserData::Privilege m_privilege;
1525     bool m_properNamespace;
1526 };
1527
1528 class CategoryParser : public ElementParser
1529 {
1530   public:
1531     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1532                                         const DPL::String& /*name*/)
1533     {
1534         return &IgnoringParser::Create;
1535     }
1536
1537     virtual void Accept(const XmlAttribute& attribute)
1538     {
1539         if (attribute.name == L"name") {
1540             if (attribute.value.size() > 0) {
1541                 m_name = attribute.value;
1542             }
1543         }
1544     }
1545
1546     virtual void Accept(const Element& /*element*/)
1547     {}
1548
1549     virtual void Accept(const Text& /*text*/)
1550     {}
1551
1552     virtual void Verify()
1553     {
1554         if (m_name.IsNull()) {
1555             LogWarning(
1556                 "name attribute of category element is mandatory - ignoring");
1557             return;
1558         }
1559
1560         if (m_data.categoryList.find(*m_name) ==
1561             m_data.categoryList.end())
1562         {
1563             m_data.categoryList.insert(*m_name);
1564         }
1565     }
1566
1567     explicit CategoryParser(ConfigParserData& data) :
1568         m_data(data)
1569     {}
1570
1571   private:
1572     DPL::OptionalString m_name;
1573     ConfigParserData& m_data;
1574 };
1575
1576 class AppWidgetParser : public ElementParser
1577 {
1578   public:
1579
1580     struct BoxLabelParser : public ElementParser
1581     {
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
1591         virtual void Accept(const Element& element)
1592         {
1593             if (element.ns ==
1594                 ConfigurationNamespace::TizenWebAppNamespaceName)
1595             {
1596                 m_properNamespace = true;
1597             }
1598         }
1599
1600         virtual void Accept(const Text& text)
1601         {
1602             if (m_properNamespace) {
1603                 m_label = text.value;
1604             }
1605         }
1606
1607         virtual void Verify()
1608         {
1609             m_data.m_label = m_label;
1610         }
1611
1612         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1613             ElementParser(),
1614             m_properNamespace(false),
1615             m_data(data)
1616         {}
1617
1618       private:
1619         DPL::String m_label;
1620         bool m_properNamespace;
1621         ConfigParserData::LiveboxInfo& m_data;
1622     };
1623
1624     struct BoxIconParser : public ElementParser
1625     {
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 XmlAttribute& attribute)
1633         {
1634             if (m_properNamespace) {
1635                 if (attribute.name == L"src") {
1636                     m_icon = attribute.value;
1637                 }
1638             }
1639         }
1640
1641         virtual void Accept(const Element& element)
1642         {
1643             if (element.ns ==
1644                 ConfigurationNamespace::TizenWebAppNamespaceName)
1645             {
1646                 m_properNamespace = true;
1647             }
1648         }
1649
1650         virtual void Accept(const Text& /*text*/)
1651         {}
1652
1653         virtual void Verify()
1654         {
1655             m_data.m_icon = m_icon;
1656         }
1657
1658         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1659             ElementParser(),
1660             m_properNamespace(false),
1661             m_data(data)
1662         {}
1663
1664       private:
1665         DPL::String m_icon;
1666         bool m_properNamespace;
1667         ConfigParserData::LiveboxInfo& m_data;
1668     };
1669
1670     struct BoxContentParser : public ElementParser
1671     {
1672         struct BoxSizeParser : public ElementParser
1673         {
1674             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1675                                                 const DPL::String& /*name*/)
1676             {
1677                 return &IgnoringParser::Create;
1678             }
1679
1680             virtual void Accept(const XmlAttribute& attribute)
1681             {
1682                 if (m_properNamespace) {
1683                     if (attribute.name == L"preview") {
1684                         m_preview = attribute.value;
1685                     }
1686                 }
1687             }
1688
1689             virtual void Accept(const Element& element)
1690             {
1691                 if (element.ns ==
1692                     ConfigurationNamespace::TizenWebAppNamespaceName)
1693                 {
1694                     m_properNamespace = true;
1695                 }
1696             }
1697
1698             virtual void Accept(const Text& text)
1699             {
1700                 if (m_properNamespace) {
1701                     m_size = text.value;
1702                 }
1703             }
1704
1705             virtual void Verify()
1706             {
1707                 std::pair<DPL::String, DPL::String> boxSize;
1708                 boxSize.first = m_size;
1709                 boxSize.second = m_preview;
1710                 m_data.m_boxSize.push_back(boxSize);
1711             }
1712
1713             explicit BoxSizeParser(
1714                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1715                 ElementParser(),
1716                 m_properNamespace(false),
1717                 m_data(data)
1718             {}
1719
1720           private:
1721             DPL::String m_size;
1722             DPL::String m_preview;
1723             bool m_properNamespace;
1724             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1725         };
1726
1727         struct PdParser : public ElementParser
1728         {
1729             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1730                                                 const DPL::String& /*name*/)
1731             {
1732                 return &IgnoringParser::Create;
1733             }
1734
1735             virtual void Accept(const XmlAttribute& attribute)
1736             {
1737                 if (m_properNamespace) {
1738                     if (attribute.name == L"src") {
1739                         m_src = attribute.value;
1740                     } else if (attribute.name == L"width") {
1741                         m_width = attribute.value;
1742                     } else if (attribute.name == L"height") {
1743                         m_height = attribute.value;
1744                     } else if (attribute.name == L"fast-open") {
1745                         m_fastOpen= attribute.value;
1746                     }
1747                 }
1748             }
1749
1750             virtual void Accept(const Element& element)
1751             {
1752                 if (element.ns ==
1753                     ConfigurationNamespace::TizenWebAppNamespaceName)
1754                 {
1755                     m_properNamespace = true;
1756                 }
1757             }
1758
1759             virtual void Accept(const Text& /*text*/)
1760             {}
1761
1762             virtual void Verify()
1763             {
1764                 m_data.m_pdSrc = m_src;
1765                 m_data.m_pdWidth = m_width;
1766                 m_data.m_pdHeight = m_height;
1767                 m_data.m_pdFastOpen = m_fastOpen;
1768             }
1769
1770             explicit PdParser(
1771                 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1772                 ElementParser(),
1773                 m_properNamespace(false),
1774                 m_data(data)
1775             {}
1776
1777           private:
1778             DPL::String m_src;
1779             DPL::String m_width;
1780             DPL::String m_height;
1781             DPL::String m_fastOpen;
1782
1783             bool m_properNamespace;
1784             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1785         };
1786
1787         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1788                                             const DPL::String& name)
1789         {
1790             if (name == L"box-size") {
1791                 return DPL::MakeDelegate(
1792                            this,
1793                            &AppWidgetParser::BoxContentParser::
1794                                OnBoxSizeElement);
1795             } else if (name == L"pd") {
1796                 return DPL::MakeDelegate(
1797                            this,
1798                            &AppWidgetParser::BoxContentParser::
1799                                OnPdElement);
1800             } else {
1801                 ThrowMsg(Exception::ParseError,
1802                          "No element parser for name: " << name);
1803             }
1804         }
1805
1806         virtual void Accept(const XmlAttribute& attribute)
1807         {
1808             if (m_properNamespace) {
1809                 if (attribute.name == L"src") {
1810                     m_box.m_boxSrc = attribute.value;
1811                 }
1812                 if (attribute.name == L"mouse-event") {
1813                     m_box.m_boxMouseEvent = attribute.value;
1814                 }
1815                 if (attribute.name == L"touch-effect") {
1816                     m_box.m_boxTouchEffect = attribute.value;
1817                 }
1818             }
1819         }
1820
1821         virtual void Accept(const Element& element)
1822         {
1823             if (element.ns ==
1824                 ConfigurationNamespace::TizenWebAppNamespaceName)
1825             {
1826                 m_properNamespace = true;
1827             }
1828         }
1829
1830         virtual void Accept(const Text& /*text*/)
1831         {}
1832
1833         virtual void Verify()
1834         {
1835             m_data.m_boxInfo = m_box;
1836         }
1837
1838         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1839             ElementParser(),
1840             m_properNamespace(false),
1841             m_data(data)
1842         {}
1843
1844         ElementParserPtr OnBoxSizeElement()
1845         {
1846             return ElementParserPtr(new BoxSizeParser(m_box));
1847         }
1848
1849         ElementParserPtr OnPdElement()
1850         {
1851             return ElementParserPtr(new PdParser(m_box));
1852         }
1853
1854       private:
1855         DPL::String m_src;
1856         bool m_properNamespace;
1857         ConfigParserData::LiveboxInfo& m_data;
1858         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1859     };
1860
1861     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1862                                         const DPL::String& name)
1863     {
1864         if (name == L"box-label") {
1865             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
1866         } else if (name == L"box-icon") {
1867             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
1868         } else if (name == L"box-content") {
1869             return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
1870         } else {
1871             return &IgnoringParser::Create;
1872         }
1873     }
1874
1875     virtual void Accept(const XmlAttribute& attribute)
1876     {
1877         if (m_properNamespace) {
1878             if (attribute.name == L"id") {
1879                 m_liveboxId = attribute.value;
1880             } else if (attribute.name == L"primary") {
1881                 m_primary = attribute.value;
1882             } else if (attribute.name == L"auto-launch") {
1883                 m_autoLaunch = attribute.value;
1884             } else if (attribute.name == L"update-period") {
1885                 m_updatePeriod = attribute.value;
1886             } else if (attribute.name == L"type") {
1887                 m_type = attribute.value;
1888             }
1889         }
1890     }
1891
1892     virtual void Accept(const Element& element)
1893     {
1894         if (element.ns ==
1895             ConfigurationNamespace::TizenWebAppNamespaceName)
1896         {
1897             m_properNamespace = true;
1898         }
1899     }
1900
1901     virtual void Accept(const Text& /*text*/)
1902     {}
1903
1904     virtual void Verify()
1905     {
1906         m_livebox.m_liveboxId = m_liveboxId;
1907         m_livebox.m_primary = m_primary;
1908         m_livebox.m_autoLaunch = m_autoLaunch;
1909         m_livebox.m_updatePeriod = m_updatePeriod;
1910         m_livebox.m_type = m_type;
1911
1912         m_data.m_livebox.push_back(m_livebox);
1913     }
1914
1915     explicit AppWidgetParser(ConfigParserData& data) :
1916         ElementParser(),
1917         m_data(data),
1918         m_properNamespace(false)
1919     {
1920         m_livebox = ConfigParserData::LiveboxInfo();
1921     }
1922
1923     ElementParserPtr OnBoxLabelElement()
1924     {
1925         return ElementParserPtr(new BoxLabelParser(m_livebox));
1926     }
1927
1928     ElementParserPtr OnBoxIconElement()
1929     {
1930         return ElementParserPtr(new BoxIconParser(m_livebox));
1931     }
1932
1933     ElementParserPtr OnBoxContentElement()
1934     {
1935         return ElementParserPtr(new BoxContentParser(m_livebox));
1936     }
1937
1938   private:
1939     ConfigParserData& m_data;
1940     ConfigParserData::LiveboxInfo m_livebox;
1941     DPL::String m_liveboxId;
1942     DPL::String m_primary;
1943     DPL::String m_autoLaunch;
1944     DPL::String m_updatePeriod;
1945     DPL::String m_type;
1946     bool m_properNamespace;
1947 };
1948
1949 class AllowNavigationParser : public ElementParser
1950 {
1951   public:
1952     AllowNavigationParser(ConfigParserData& data) :
1953       ElementParser(),
1954       m_data(data),
1955       m_properNamespace(false)
1956     {}
1957
1958     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1959                                         const DPL::String& /*name*/)
1960     {
1961         return &IgnoringParser::Create;
1962     }
1963
1964     virtual void Accept(const Element& element)
1965     {
1966         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
1967             m_properNamespace = true;
1968         }
1969     }
1970
1971     virtual void Accept(const Text& text)
1972     {
1973         if (m_properNamespace) {
1974             m_origin = text.value;
1975         }
1976     }
1977
1978     virtual void Accept(const XmlAttribute& /*attribute*/)
1979     {
1980     }
1981
1982     virtual void Verify()
1983     {
1984         if (m_origin.IsNull()) {
1985             LogWarning("data is empty");
1986             return;
1987         }
1988
1989         char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
1990         char* ptr = strtok(data," ");
1991         while (ptr != NULL) {
1992             std::string origin = ptr;
1993             ptr = strtok(NULL," ");
1994             if(origin == "*") {
1995                 ConfigParserData::AllowNavigationInfo info(L"*", L"*");
1996                 m_data.allowNavigationInfoList.push_back(info);
1997                 continue;
1998             }
1999
2000             DPL::ScopedPtr<iri_t> iri(iri_parse(origin.c_str()));
2001             if (!iri->host || strlen(iri->host) == 0) {
2002                 // input origin should has schem and host
2003                 // in case of file scheme path is filled
2004                 // "http://"
2005                 LogWarning("input origin isn't verified");
2006                 continue;
2007             }
2008             DPL::String scheme = L"*";
2009             if (iri->scheme && strlen(iri->scheme) != 0) {
2010                 scheme = DPL::FromUTF8String(iri->scheme);
2011             }
2012             ConfigParserData::AllowNavigationInfo info(
2013                 scheme,
2014                 DPL::FromUTF8String(iri->host));
2015             m_data.allowNavigationInfoList.push_back(info);
2016         }
2017         free(data);
2018     }
2019
2020   private:
2021     DPL::OptionalString m_origin;
2022     ConfigParserData& m_data;
2023     bool m_properNamespace;
2024 };
2025
2026 class CspParser : public ElementParser
2027 {
2028   public:
2029     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2030                                         const DPL::String& /*name*/)
2031     {
2032         return &IgnoringParser::Create;
2033     }
2034
2035     CspParser(ConfigParserData& data) :
2036         ElementParser(),
2037         m_data(data),
2038         m_properNamespace(false)
2039     {}
2040
2041     virtual void Accept(const Element& element)
2042     {
2043         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2044             m_properNamespace = true;
2045         }
2046     }
2047
2048     virtual void Accept(const XmlAttribute& /*attribute*/)
2049     {}
2050
2051     virtual void Accept(const Text& text)
2052     {
2053         if (m_properNamespace) {
2054             m_policy = text.value;
2055         }
2056     }
2057
2058     virtual void Verify()
2059     {
2060         if (!m_policy.IsNull()) {
2061             m_data.cspPolicy = *m_policy;
2062         }
2063     }
2064
2065   private:
2066     ConfigParserData& m_data;
2067     bool m_properNamespace;
2068     DPL::OptionalString m_policy;
2069 };
2070
2071 class CspReportOnlyParser : public ElementParser
2072 {
2073   public:
2074     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2075                                         const DPL::String& /*name*/)
2076     {
2077         return &IgnoringParser::Create;
2078     }
2079
2080     CspReportOnlyParser(ConfigParserData& data) :
2081         ElementParser(),
2082         m_data(data),
2083         m_properNamespace(false)
2084     {}
2085
2086     virtual void Accept(const Element& element)
2087     {
2088         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2089             m_properNamespace = true;
2090         }
2091     }
2092
2093     virtual void Accept(const XmlAttribute& /*attribute*/)
2094     {}
2095
2096     virtual void Accept(const Text& text)
2097     {
2098         if (m_properNamespace) {
2099             m_policy = text.value;
2100         }
2101     }
2102
2103     virtual void Verify()
2104     {
2105         if (!m_policy.IsNull()) {
2106             m_data.cspPolicyReportOnly = *m_policy;
2107         }
2108     }
2109
2110   private:
2111     ConfigParserData& m_data;
2112     bool m_properNamespace;
2113     DPL::OptionalString m_policy;
2114 };
2115
2116 class AccountParser : public ElementParser
2117 {
2118   public:
2119     struct AccountProviderParser : public ElementParser
2120     {
2121       public:
2122
2123           struct IconParser : public ElementParser
2124         {
2125             public:
2126                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2127                         const DPL::String& /*name*/)
2128                 {
2129                     return &IgnoringParser::Create;
2130                 }
2131
2132                 virtual void Accept(const Text& text)
2133                 {
2134                     if (text.value == L"") {
2135                         return;
2136                     }
2137                     m_value = text.value;
2138                 }
2139
2140                 virtual void Accept(const Element& /*element*/)
2141                 {}
2142
2143                 virtual void Accept(const XmlAttribute& attribute)
2144                 {
2145                     if (attribute.name == L"section") {
2146                         if (attribute.value == L"account") {
2147                             m_type = ConfigParserData::IconSectionType::DefaultIcon;
2148                         } else if (attribute.value == L"account-small") {
2149                             m_type = ConfigParserData::IconSectionType::SmallIcon;
2150                         }
2151                     }
2152                 }
2153
2154                 virtual void Verify()
2155                 {
2156                     if (m_value.IsNull() || *m_value == L"") {
2157                         return;
2158                     }
2159
2160                     std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2161                     icon.first = m_type;
2162                     icon.second = *m_value;
2163
2164                     m_data.m_iconSet.insert(icon);
2165                 }
2166
2167                 IconParser(ConfigParserData::AccountProvider& data) :
2168                     ElementParser(),
2169                     m_properNamespace(false),
2170                     m_type(ConfigParserData::DefaultIcon),
2171                     m_data(data)
2172             {}
2173
2174             private:
2175                 bool m_properNamespace;
2176                 ConfigParserData::IconSectionType m_type;
2177                 ConfigParserData::AccountProvider& m_data;
2178                 DPL::OptionalString m_value;
2179         };
2180
2181           struct DisplayNameParser : public ElementParser
2182         {
2183             public:
2184                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2185                         const DPL::String& /*name*/)
2186                 {
2187                     return &IgnoringParser::Create;
2188                 }
2189
2190                 virtual void Accept(const Text& text)
2191                 {
2192                     if (text.value == L"") {
2193                         return;
2194                     }
2195                     m_value = text.value;
2196                 }
2197
2198                 virtual void Accept(const Element& element)
2199                 {
2200                     m_lang = element.lang;
2201                     m_value= L"";
2202                 }
2203
2204                 virtual void Accept(const XmlAttribute& /*attribute*/)
2205                 {}
2206
2207                 virtual void Verify()
2208                 {
2209                     if (m_value.IsNull() || *m_value == L"") {
2210                         return;
2211                     }
2212
2213                     std::pair<DPL::String, DPL::String> name;
2214                     name.first = *m_lang;
2215                     name.second = *m_value;
2216
2217                     m_data.m_displayNameSet.insert(name);
2218                 }
2219
2220                 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2221                     ElementParser(),
2222                     m_properNamespace(false),
2223                     m_data(data)
2224             {}
2225
2226             private:
2227                 bool m_properNamespace;
2228                 DPL::OptionalString m_lang;
2229                 DPL::OptionalString m_value;
2230                 ConfigParserData::AccountProvider& m_data;
2231         };
2232
2233           struct CapabilityParser : public ElementParser
2234         {
2235             public:
2236                 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2237                         const DPL::String& /*name*/)
2238                 {
2239                     return &IgnoringParser::Create;
2240                 }
2241
2242                 virtual void Accept(const Text& text)
2243                 {
2244                     if (text.value == L"") {
2245                         return;
2246                     }
2247                     m_value = text.value;
2248                 }
2249
2250                 virtual void Accept(const Element& /*element*/)
2251                 {}
2252
2253                 virtual void Accept(const XmlAttribute& /*attribute*/)
2254                 {}
2255
2256                 virtual void Verify()
2257                 {
2258                     if (m_value.IsNull() || *m_value == L"") {
2259                         return;
2260                     }
2261                     m_data.m_capabilityList.push_back(*m_value);
2262                 }
2263
2264                 CapabilityParser(ConfigParserData::AccountProvider& data) :
2265                     ElementParser(),
2266                     m_properNamespace(false),
2267                     m_data(data)
2268             {}
2269
2270             private:
2271                 bool m_properNamespace;
2272                 DPL::OptionalString m_value;
2273                 ConfigParserData::AccountProvider& m_data;
2274         };
2275           virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2276                   const DPL::String& name)
2277           {
2278               if (name == L"icon") {
2279                   return DPL::MakeDelegate(this, &AccountProviderParser::OnIconElement);
2280               } else if (name == L"display-name") {
2281                   return DPL::MakeDelegate(this,
2282                           &AccountProviderParser::OnDisplayNameElement);
2283               } else if (name == L"capability") {
2284                   return DPL::MakeDelegate(this, &AccountProviderParser::OnCapabilityElement);
2285               } else {
2286                   return &IgnoringParser::Create;
2287               }
2288           }
2289
2290           virtual void Accept(const Text& /*text*/)
2291           {}
2292
2293           virtual void Accept(const Element& /*element*/)
2294           {}
2295
2296           virtual void Accept(const XmlAttribute& attribute)
2297           {
2298               if (attribute.name == L"multiple-accounts-support") {
2299                   if (attribute.value == L"") {
2300                       return;
2301                   }
2302
2303                   if (attribute.value == L"ture") {
2304                       m_multiSupport = true;
2305                   }
2306               }
2307           }
2308
2309           virtual void Verify()
2310           {
2311               m_data.m_multiAccountSupport = m_multiSupport;
2312           }
2313
2314           ElementParserPtr OnIconElement()
2315           {
2316               return ElementParserPtr(new IconParser(m_data));
2317           }
2318
2319           ElementParserPtr OnDisplayNameElement()
2320           {
2321               return ElementParserPtr(new DisplayNameParser(m_data));
2322           }
2323
2324           ElementParserPtr OnCapabilityElement()
2325           {
2326               return ElementParserPtr(new CapabilityParser(m_data));
2327           }
2328
2329           AccountProviderParser(ConfigParserData::AccountProvider& data) :
2330               ElementParser(),
2331               m_properNamespace(false),
2332               m_multiSupport(false),
2333               m_data(data)
2334         {}
2335
2336       private:
2337           bool m_properNamespace;
2338           bool m_multiSupport;
2339           ConfigParserData::AccountProvider& m_data;
2340     };
2341
2342     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2343             const DPL::String& name)
2344     {
2345         if (name == L"account-provider") {
2346             return DPL::MakeDelegate(this, &AccountParser::OnProviderElement);
2347         } else {
2348             return &IgnoringParser::Create;
2349         }
2350     }
2351
2352     virtual void Accept(const Element& element)
2353     {
2354         if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2355             m_properNamespace = true;
2356         }
2357     }
2358
2359     virtual void Accept(const XmlAttribute& /*attribute*/)
2360     {}
2361
2362     virtual void Accept(const Text& /*text*/)
2363     {}
2364
2365     virtual void Verify()
2366     {}
2367
2368     ElementParserPtr OnProviderElement()
2369     {
2370         return ElementParserPtr(new AccountProviderParser(m_account));
2371     }
2372
2373     AccountParser(ConfigParserData& data) :
2374         ElementParser(),
2375         m_data(data),
2376         m_account(data.accountProvider),
2377         m_properNamespace(false),
2378         m_multiSupport(false)
2379     {}
2380
2381   private:
2382     ConfigParserData& m_data;
2383     ConfigParserData::AccountProvider& m_account;
2384     bool m_properNamespace;
2385     bool m_multiSupport;
2386 };
2387
2388 ElementParser::ActionFunc WidgetParser::GetElementParser(
2389     const DPL::String& /*ns*/,
2390     const DPL::String&
2391     name)
2392 {
2393     FuncMap::const_iterator it = m_map.find(name);
2394     if (it != m_map.end()) {
2395         return it->second;
2396     } else {
2397         return &IgnoringParser::Create;
2398     }
2399 }
2400
2401 WidgetParser::WidgetParser(ConfigParserData& data) :
2402     m_data(data),
2403     m_textDirection(Unicode::EMPTY)
2404 {
2405     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2406     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2407     m_map[L"description"] =
2408         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2409     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2410     m_map[L"license"] =
2411         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2412     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2413     m_map[L"content"] =
2414         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2415     m_map[L"preference"] =
2416         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2417     m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement);
2418     m_map[L"setting"] =
2419         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2420     m_map[L"application"] = DPL::MakeDelegate(
2421             this,
2422             &WidgetParser::
2423                 OnApplicationElement);
2424     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2425     m_map[L"background"] = DPL::MakeDelegate(this,
2426                                              &WidgetParser::OnBackgroundElement);
2427     m_map[L"privilege"] = DPL::MakeDelegate(this,
2428                                             &WidgetParser::OnPrivilegeElement);
2429     m_map[L"app-control"] = DPL::MakeDelegate(
2430             this,
2431             &WidgetParser::
2432                 OnAppControlElement);
2433     m_map[L"category"] = DPL::MakeDelegate(this,
2434                                            &WidgetParser::OnCategoryElement);
2435     m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
2436 #ifdef CSP_ENABLED
2437     m_map[L"content-security-policy"] = DPL::MakeDelegate(
2438             this,
2439             &WidgetParser::
2440                 OnCspElement);
2441     m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
2442             this,
2443             &WidgetParser::
2444                 OnCspReportOnlyElement);
2445 #endif
2446 #ifdef ALLOW_NAVIGATION_ENABLED
2447     m_map[L"allow-navigation"] =
2448         DPL::MakeDelegate(this, &WidgetParser::OnAllowNavigationElement);
2449 #endif
2450     m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
2451 }
2452
2453 ElementParserPtr WidgetParser::OnNameElement()
2454 {
2455     return ElementParserPtr(new NameParser(m_textDirection, m_data));
2456 }
2457
2458 ElementParserPtr WidgetParser::OnAccessElement()
2459 {
2460     return ElementParserPtr(new AccessParser(m_data));
2461 }
2462
2463 ElementParserPtr WidgetParser::OnDescriptionElement()
2464 {
2465     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2466 }
2467
2468 ElementParserPtr WidgetParser::OnAuthorElement()
2469 {
2470     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2471 }
2472
2473 ElementParserPtr WidgetParser::OnLicenseElement()
2474 {
2475     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2476 }
2477
2478 ElementParserPtr WidgetParser::OnIconElement()
2479 {
2480     return ElementParserPtr(new IconParser(m_data));
2481 }
2482
2483 ElementParserPtr WidgetParser::OnContentElement()
2484 {
2485     return ElementParserPtr(new ContentParser(m_data));
2486 }
2487
2488 ElementParserPtr WidgetParser::OnPreferenceElement()
2489 {
2490     return ElementParserPtr(new PreferenceParser(m_data));
2491 }
2492
2493 ElementParserPtr WidgetParser::OnLinkElement()
2494 {
2495     return ElementParserPtr(new LinkParser(m_data));
2496 }
2497
2498 ElementParserPtr WidgetParser::OnSettingElement()
2499 {
2500     return ElementParserPtr(new SettingParser(m_data));
2501 }
2502
2503 ElementParserPtr WidgetParser::OnApplicationElement()
2504 {
2505     return ElementParserPtr(new ApplicationParser(m_data));
2506 }
2507
2508 ElementParserPtr WidgetParser::OnSplashElement()
2509 {
2510     return ElementParserPtr(new SplashParser(m_data));
2511 }
2512
2513 ElementParserPtr WidgetParser::OnBackgroundElement()
2514 {
2515     return ElementParserPtr(new BackgroundParser(m_data));
2516 }
2517
2518 ElementParserPtr WidgetParser::OnPrivilegeElement()
2519 {
2520     return ElementParserPtr(new PrivilegeParser(m_data));
2521 }
2522
2523 ElementParserPtr WidgetParser::OnAppControlElement()
2524 {
2525     return ElementParserPtr(new AppControlParser(m_data));
2526 }
2527
2528 ElementParserPtr WidgetParser::OnCategoryElement()
2529 {
2530     return ElementParserPtr(new CategoryParser(m_data));
2531 }
2532
2533 ElementParserPtr WidgetParser::OnAppWidgetElement()
2534 {
2535     return ElementParserPtr(new AppWidgetParser(m_data));
2536 }
2537
2538 ElementParserPtr WidgetParser::OnCspElement()
2539 {
2540     return ElementParserPtr(new CspParser(m_data));
2541 }
2542
2543 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
2544 {
2545     return ElementParserPtr(new CspReportOnlyParser(m_data));
2546 }
2547
2548 ElementParserPtr WidgetParser::OnAllowNavigationElement()
2549 {
2550     return ElementParserPtr(new AllowNavigationParser(m_data));
2551 }
2552
2553 ElementParserPtr WidgetParser::OnAccountElement()
2554 {
2555     return ElementParserPtr(new AccountParser(m_data));
2556 }
2557
2558 void WidgetParser::Accept(const Element& element)
2559 {
2560     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2561         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2562     {
2563         ThrowMsg(Exception::ParseError,
2564                  "Wrong xml namespace for widget element");
2565     }
2566 }
2567
2568 void WidgetParser::Accept(const Text& /*text*/)
2569 {
2570     ThrowMsg(Exception::ParseError, "widged element must be empty");
2571 }
2572
2573 void WidgetParser::Accept(const XmlAttribute& attribute)
2574 {
2575     if (attribute.name == L"id") {
2576         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2577         //If may important tests starts to fail this test we will have
2578         //to consider commenting this test out again.
2579         if (iri.Validate()) {
2580             m_data.widget_id = attribute.value;
2581             NormalizeString(m_data.widget_id);
2582         } else {
2583             LogWarning("Widget id validation failed: " << attribute.value);
2584         }
2585     } else if (attribute.name == L"version") {
2586         m_version = attribute.value;
2587         NormalizeString(m_version);
2588     } else if (attribute.name == L"min-version") {
2589         LogInfo("min-version attribute was found. Value: " << attribute.value);
2590         m_minVersion = attribute.value;
2591         NormalizeString(m_minVersion);
2592         m_data.minVersionRequired = m_minVersion;
2593     } else if (attribute.name == L"height") {
2594         DPL::OptionalString value = attribute.value;
2595         NormalizeString(value);
2596         std::string v = DPL::ToUTF8String(*value);
2597
2598         if (!v.empty()) {
2599             unsigned char c = v.c_str()[0];
2600             if (c >= '0' && c <= '9') {
2601                 int val = 0;
2602                 for (size_t i = 0; i < v.size(); ++i) {
2603                     c = v.c_str()[i];
2604                     if (c >= '0' && c <= '9') {
2605                         val *= 10;
2606                         val += (c - '0');
2607                     } else {
2608                         break;
2609                     }
2610                 }
2611                 m_data.height = val;
2612             }
2613         }
2614     } else if (attribute.name == L"width") {
2615         DPL::OptionalString value = attribute.value;
2616         NormalizeString(value);
2617         std::string v = DPL::ToUTF8String(*value);
2618
2619         if (!v.empty()) {
2620             unsigned char c = v.c_str()[0];
2621             if (c >= '0' && c <= '9') {
2622                 int val = 0;
2623                 for (size_t i = 0; i < v.size(); ++i) {
2624                     c = v.c_str()[i];
2625                     if (c >= '0' && c <= '9') {
2626                         val *= 10;
2627                         val += (c - '0');
2628                     } else {
2629                         break;
2630                     }
2631                 }
2632                 m_data.width = val;
2633             }
2634         }
2635     } else if (attribute.name == L"viewmodes") {
2636         DPL::Tokenize(attribute.value,
2637                       L" ",
2638                       std::inserter(m_windowModes,
2639                                     m_windowModes.end()),
2640                       true);
2641     } else if (attribute.name == L"dir") {
2642         m_textDirection = Unicode::ParseDirAttribute(attribute);
2643     } else if (L"defaultlocale" == attribute.name) {
2644         if (!m_defaultlocale) {
2645             m_defaultlocale = attribute.value;
2646             NormalizeString(m_defaultlocale);
2647             if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag(
2648                     DPL::ToUTF8String(*m_defaultlocale)))
2649             {
2650                 LogWarning("Language tag: " <<
2651                            m_defaultlocale << " is not valid");
2652                 m_defaultlocale = DPL::OptionalString::Null;
2653             } else {
2654                 LogDebug("Default Locale Found " << m_defaultlocale);
2655             }
2656         } else {
2657             LogWarning("Ignoring subsequent default locale");
2658         }
2659
2660         //Any other value consider as a namespace definition
2661     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2662         LogInfo("Namespace domain: " << attribute.name);
2663         LogInfo("Namespace value: " << attribute.value);
2664         m_nameSpaces[attribute.name] = attribute.value;
2665     } else {
2666         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2667                  ", name=" << attribute.name <<
2668                  ", value=" << attribute.value);
2669     }
2670 }
2671
2672 void WidgetParser::Verify()
2673 {
2674     FOREACH(mode, m_windowModes) {
2675         if (L"windowed" == *mode || L"floating" == *mode ||
2676             L"fullscreen" == *mode || L"maximized" == *mode ||
2677             L"minimized" == *mode)
2678         {
2679             m_data.windowModes.insert(*mode);
2680         }
2681     }
2682     if (!m_version.IsNull()) {
2683         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2684         m_data.version = m_version;
2685     }
2686     m_data.defaultlocale = m_defaultlocale;
2687     FOREACH(ns, m_nameSpaces) {
2688         m_data.nameSpaces.insert(ns->second);
2689     }
2690 }
2691