[Release] wrt-installer_0.0.89
[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     }
92 }
93 } // namespace Unicode
94
95 class InnerElementsParser : public ElementParser
96 {
97   public:
98     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
99             const DPL::String& /*name*/)
100     {
101         return DPL::MakeDelegate(this, &InnerElementsParser::Other);
102     }
103
104     virtual void Accept(const Element& /*element*/)
105     {
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
139     ElementParserPtr Other()
140     {
141         return ElementParserPtr(new InnerElementsParser(
142                                     std::static_pointer_cast<ElementParser>(
143                                         shared_from_this())));
144     }
145
146   private:
147     DPL::Optional<Text> m_text;
148     ElementParserPtr m_parentParser;
149     Unicode::Direction m_textDirection;
150 };
151
152 class NameParser : public ElementParser
153 {
154   public:
155     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
156             const DPL::String& /*name*/)
157     {
158         return DPL::MakeDelegate(this, &NameParser::Other);
159     }
160
161     virtual void Accept(const Element& element)
162     {
163         m_lang = element.lang;
164         m_name = L"";
165     }
166
167     virtual void Accept(const Text& text)
168     {
169         if (m_name.IsNull()) {
170             m_name = text.value;
171         } else {
172             *m_name += text.value;
173         }
174     }
175
176     virtual void Accept(const XmlAttribute& attribute)
177     {
178         if (attribute.name == L"short") {
179             if (m_shortName.IsNull()) {
180                 m_shortName = attribute.value;
181             }
182         } else if (attribute.name == L"dir") {
183             m_textDirection = Unicode::ParseDirAttribute(attribute);
184         }
185     }
186
187     virtual void Verify()
188     {
189         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
190         if (data.name.IsNull()) {
191             NormalizeString(m_name);
192             NormalizeString(m_shortName);
193             if (!m_name.IsNull()) {
194                 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
195             }
196             data.name = m_name;
197             if (!m_shortName.IsNull()) {
198                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
199                                                      &*m_shortName);
200             }
201             data.shortName = m_shortName;
202         }
203     }
204
205     NameParser(Unicode::Direction direction,
206             ConfigParserData& data) :
207         m_data(data),
208         m_textDirection(direction)
209     {
210     }
211
212     ElementParserPtr Other()
213     {
214         return ElementParserPtr(new InnerElementsParser(
215                                     std::static_pointer_cast<ElementParser>(
216                                         shared_from_this())));
217     }
218
219   private:
220     ConfigParserData& m_data;
221     DPL::OptionalString m_name;
222     DPL::OptionalString m_shortName;
223     DPL::OptionalString m_dir;
224     DPL::String m_lang;
225     Unicode::Direction m_textDirection;
226 };
227
228 class AccessParser : public ElementParser
229 {
230   public:
231     enum StandardType
232     {
233         STANDARD_TYPE_NONE,
234         STANDARD_TYPE_WARP
235     };
236
237     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
238             const DPL::String& /*name*/)
239     {
240         return DPL::MakeDelegate(this, &AccessParser::Other);
241     }
242
243     virtual void Accept(const Element& element)
244     {
245         // for tizen web apps WARP should be used
246         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
247             element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
248         {
249             m_standardType = STANDARD_TYPE_WARP;
250         }
251     }
252
253     virtual void Accept(const Text& /*text*/)
254     {
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         }
283     }
284
285     void VerifyWac()
286     {
287         WarpIRI iri;
288         iri.set(m_strIRIOrigin, false);
289
290         if (!iri.isAccessDefinition()) {
291             LogWarning("Access list element: " <<
292                        m_strIRIOrigin <<
293                        " is not acceptable by WARP" <<
294                        "standard and will be ignored!");
295             return;
296         }
297
298         ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
299                                                 m_bSubDomainAccess);
300         std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
301             m_data.accessInfoSet.insert(accessInfo);
302     }
303
304     virtual void Verify()
305     {
306         switch (m_standardType) {
307         case STANDARD_TYPE_WARP:
308             VerifyWac();
309             break;
310         default:
311             LogError("Error in Access tag - unknown standard.");
312         }
313     }
314
315     AccessParser(ConfigParserData& data) :
316         ElementParser(),
317         m_bSubDomainAccess(false),
318         m_standardType(STANDARD_TYPE_NONE),
319         m_network(false),
320         m_data(data)
321     {
322     }
323
324     ElementParserPtr Other()
325     {
326         return ElementParserPtr(new InnerElementsParser(
327                                     ElementParserPtr(shared_from_this())));
328     }
329
330   private:
331     DPL::String m_strIRIOrigin;
332     bool m_bSubDomainAccess;
333     StandardType m_standardType;
334     bool m_network;
335     ConfigParserData& m_data;
336 };
337
338 class DescriptionParser : public ElementParser
339 {
340   public:
341     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
342             const DPL::String& /*name*/)
343     {
344         return DPL::MakeDelegate(this, &DescriptionParser::Other);
345     }
346
347     virtual void Accept(const Element& element)
348     {
349         m_lang = element.lang;
350         m_description = L"";
351     }
352
353     ElementParserPtr Other()
354     {
355         return ElementParserPtr(new InnerElementsParser(
356                                     std::static_pointer_cast<ElementParser>(
357                                         shared_from_this())));
358     }
359
360     virtual void Accept(const Text& text)
361     {
362         if (m_description.IsNull()) {
363             m_description = text.value;
364         } else {
365             *m_description += text.value;
366         }
367     }
368
369     virtual void Accept(const XmlAttribute& attribute)
370     {
371         if (attribute.name == L"dir") {
372             m_textDirection = Unicode::ParseDirAttribute(attribute);
373         }
374     }
375
376     virtual void Verify()
377     {
378         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
379         if (data.description.IsNull()) {
380             if (!m_description.IsNull()) {
381                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
382                                                      &*m_description);
383             }
384             data.description = m_description;
385         }
386     }
387
388     DescriptionParser(Unicode::Direction direction,
389             ConfigParserData& data) :
390         m_data(data),
391         m_lang(),
392         m_description(),
393         m_textDirection(direction)
394     {
395     }
396
397   private:
398     ConfigParserData& m_data;
399     DPL::String m_lang;
400     DPL::OptionalString m_description;
401     Unicode::Direction m_textDirection;
402 };
403
404 class AuthorParser : public ElementParser
405 {
406   public:
407     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
408             const DPL::String& /*name*/)
409     {
410         return DPL::MakeDelegate(this, &AuthorParser::Other);
411     }
412
413     AuthorParser(Unicode::Direction direction,
414             ConfigParserData& data) :
415         m_data(data),
416         m_textDirection(direction)
417     {
418     }
419
420     virtual void Accept(const Element& /*element*/)
421     {
422         m_authorName = L"";
423     }
424
425     virtual void Accept(const Text& text)
426     {
427         *(m_authorName) += text.value;
428     }
429
430     virtual void Accept(const XmlAttribute& attribute)
431     {
432         if (attribute.name == L"href") {
433             //Validate href IRI and ignore it if invalid
434             //See also test: ta-argMozRiC-an
435             LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
436             if (iri.Validate()) {
437                 m_authorHref = attribute.value;
438             }
439         } else if (attribute.name == L"email") {
440             m_authorEmail = attribute.value;
441         } else if (attribute.name == L"dir") {
442             m_textDirection = Unicode::ParseDirAttribute(attribute);
443         }
444     }
445
446     virtual void Verify()
447     {
448         if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) {
449             NormalizeString(m_authorName);
450             NormalizeString(m_authorHref);
451             NormalizeString(m_authorEmail);
452             if (!!m_authorName) {
453                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
454                                                      &*m_authorName);
455                 m_data.authorName = m_authorName;
456             }
457             if (!!m_authorHref) {
458                 m_data.authorHref = m_authorHref;
459             }
460             if (!!m_authorEmail) {
461                 m_data.authorEmail = m_authorEmail;
462             }
463         }
464     }
465
466     ElementParserPtr Other()
467     {
468         return ElementParserPtr(new InnerElementsParser(
469                                     std::static_pointer_cast<ElementParser>(
470                                         shared_from_this())));
471     }
472
473   private:
474     ConfigParserData& m_data;
475     DPL::OptionalString m_authorEmail;
476     DPL::OptionalString m_authorHref;
477     DPL::OptionalString m_authorName;
478     Unicode::Direction m_textDirection;
479 };
480
481 class LicenseParser : public ElementParser
482 {
483   public:
484     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
485             const DPL::String& /*name*/)
486     {
487         return DPL::MakeDelegate(this, &LicenseParser::Other);
488     }
489
490     LicenseParser(Unicode::Direction direction,
491             ConfigParserData& data) :
492         m_data(data),
493         m_ignore(true),
494         m_textDirection(direction)
495     {
496     }
497
498     virtual void Accept(const Element& element)
499     {
500         if (m_license.IsNull()) {
501             m_lang = element.lang;
502             m_license = L"";
503             m_ignore = false;
504         }
505     }
506
507     virtual void Accept(const Text& text)
508     {
509         if (!m_ignore) {
510             *m_license += text.value;
511         }
512     }
513
514     virtual void Accept(const XmlAttribute& attribute)
515     {
516         if (!m_ignore) {
517             if (attribute.name == L"href" && m_licenseHref.IsNull()) {
518                 m_licenseHref = attribute.value;
519             } else if (attribute.name == L"file" && m_licenseFile.IsNull()) {
520                 m_licenseFile = attribute.value;
521             } else if (attribute.name == L"dir") {
522                 m_textDirection = Unicode::ParseDirAttribute(attribute);
523             }
524         }
525     }
526
527     virtual void Verify()
528     {
529         ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
530         if (data.license.IsNull()) {
531             if (!m_license.IsNull()) {
532                 Unicode::UpdateTextWithDirectionMark(m_textDirection,
533                                                      &*m_license);
534             }
535             data.license = m_license;
536             data.licenseHref = m_licenseHref;
537             data.licenseFile = m_licenseFile;
538         }
539     }
540
541     ElementParserPtr Other()
542     {
543         return ElementParserPtr(new InnerElementsParser(
544                                     ElementParserPtr(shared_from_this())));
545     }
546
547   private:
548     ConfigParserData& m_data;
549     DPL::String m_lang;
550     bool m_ignore;
551
552     DPL::OptionalString m_license;
553     DPL::OptionalString m_licenseFile;
554     DPL::OptionalString m_licenseHref;
555     Unicode::Direction m_textDirection;
556 };
557
558 class IconParser : public ElementParser
559 {
560     DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
561
562   public:
563     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
564             const DPL::String& /*name*/)
565     {
566         return &IgnoringParser::Create;
567     }
568
569     IconParser(ConfigParserData& data) : ElementParser(),
570         m_data(data)
571     {
572     }
573
574     virtual void Accept(const Element& /*element*/)
575     {
576     }
577
578     virtual void Accept(const XmlAttribute& attribute)
579     {
580         if (attribute.name == L"src") {
581             if (attribute.value.size() > 0) {
582                 m_src = attribute.value;
583             }
584         } else if (attribute.name == L"width") {
585             m_width = ParseSizeAttributeValue(attribute.value);
586         } else if (attribute.name == L"height") {
587             m_height = ParseSizeAttributeValue(attribute.value);
588         }
589     }
590
591     virtual void Accept(const Text& /*text*/)
592     {
593         ThrowMsg(Exception::ParseError, "Icon element must be empty");
594     }
595
596     virtual void Verify()
597     {
598         if (m_src.IsNull()) {
599             LogWarning("src attribute of icon element is mandatory - ignoring");
600             return;
601         }
602
603         Try
604         {
605             ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
606             icon.width = m_width;
607             icon.height = m_height;
608
609             ConfigParserData::IconsList::iterator it = std::find(
610                     m_data.iconsList.begin(), m_data.iconsList.end(), icon);
611             if (it == m_data.iconsList.end()) {
612                 m_data.iconsList.push_front(icon);
613             }
614         }
615         Catch(BadSrcError)
616         {
617             LogWarning("src attribute is invalid: " << m_src);
618         }
619     }
620
621   private:
622     ConfigParserData& m_data;
623     DPL::OptionalString m_src;
624     DPL::OptionalInt m_width;
625     DPL::OptionalInt m_height;
626
627     static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
628     {
629         DPL::OptionalString normalizedValue = value;
630         NormalizeString(normalizedValue);
631         if (!(*normalizedValue).empty()) {
632             char* reterr = NULL;
633             errno = 0;
634             long int valueInt =
635                 strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
636             if (errno != 0 ||
637                 std::string(reterr) == DPL::ToUTF8String(value) ||
638                 valueInt <= 0) {
639                 return DPL::OptionalInt::Null;
640             } else {
641                 return valueInt;
642             }
643         }
644         return DPL::OptionalInt::Null;
645     }
646
647     /**
648      * @brief delocalizePath removes locales folder from relative path if neccessary
649      * @param source source string
650      *
651      * @throw BadSrcError if string is bad value of src attribute
652      *
653      * @return corrected string
654      */
655     static DPL::String delocalizeSrcPath(const DPL::String & source)
656     {
657         static const DPL::String localeFolder(L"locales/");
658         static const int index = localeFolder.size();
659
660         DPL::String result = source;
661
662         if(source.substr(0,index) == localeFolder)
663         {
664             size_t pos = result.find_first_of('/',index);
665             if(pos != std::string::npos && pos + 1 < source.size())
666             {
667                 result = result.substr(pos + 1,source.size());
668             }
669             else
670             {
671                 Throw(BadSrcError);
672             }
673         }
674         return result;
675     }
676 };
677
678 class ContentParser : public ElementParser
679 {
680   public:
681     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
682             const DPL::String& /*name*/)
683     {
684         return &IgnoringParser::Create;
685     }
686
687     ContentParser(ConfigParserData& data) :
688         ElementParser(),
689         m_data(data)
690     {
691     }
692
693     virtual void Accept(const Element& /*element*/)
694     {
695     }
696
697     virtual void Accept(const Text& /*text*/)
698     {
699     }
700
701     virtual void Accept(const XmlAttribute& attribute)
702     {
703         DPL::String value = attribute.value;
704         NormalizeString(value);
705
706         if (attribute.name == L"src") {
707             m_src = value;
708         } else if (attribute.name == L"type") {
709             m_type = value;
710             MimeTypeUtils::MimeAttributes mimeAttributes =
711                 MimeTypeUtils::getMimeAttributes(value);
712             if (mimeAttributes.count(L"charset") > 0) {
713                 m_encoding = mimeAttributes[L"charset"];
714             }
715         } else if (attribute.name == L"encoding") {
716             if (!value.empty()) {
717                 m_encoding = value;
718             }
719         }
720     }
721
722     virtual void Verify()
723     {
724         if (m_data.startFileEncountered) {
725             LogWarning("This is not the first encountered "
726                        "'content' element - ignoring.");
727             return;
728         }
729
730         m_data.startFileEncountered = true;
731
732         //we're consciously setting startFile even if m_src is null or invalid.
733         //WidgetConfigurationManager will deal with this.
734         m_data.startFile = m_src;
735
736         if (!!m_src) {
737             m_data.startFileContentType = m_type;
738             if (!!m_encoding) {
739                 m_data.startFileEncoding = m_encoding;
740             } else {
741                 m_data.startFileEncoding = L"UTF-8";
742             }
743         }
744     }
745
746   private:
747     DPL::OptionalString m_src;
748     DPL::OptionalString m_type;
749     DPL::OptionalString m_encoding;
750     ConfigParserData& m_data;
751 };
752
753 class FeatureParser : public ElementParser
754 {
755   public:
756     struct ParamParser : public ElementParser
757     {
758         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
759                 const DPL::String& /*name*/)
760         {
761             return &IgnoringParser::Create;
762         }
763
764         virtual void Accept(const XmlAttribute& attribute)
765         {
766             if (attribute.name == L"name") {
767                 m_name = attribute.value;
768                 NormalizeString(m_name);
769             } else if (attribute.name == L"value") {
770                 m_value = attribute.value;
771                 NormalizeString(m_value);
772             }
773         }
774
775         virtual void Accept(const Element& /*element*/)
776         {
777         }
778
779         virtual void Accept(const Text& /*text*/)
780         {
781             ThrowMsg(Exception::ParseError, "param element must be empty");
782         }
783
784         virtual void Verify()
785         {
786             if (m_name.IsNull() || *m_name == L"") {
787                 return;
788             }
789             if (m_value.IsNull() || *m_value == L"") {
790                 return;
791             }
792
793             ConfigParserData::Param param(*m_name);
794             param.value = *m_value;
795
796             if (m_data.paramsList.find(param) == m_data.paramsList.end()) {
797                 m_data.paramsList.insert(param);
798             }
799         }
800
801         ParamParser(ConfigParserData::Feature& data) :
802             ElementParser(),
803             m_data(data)
804         {
805         }
806
807       private:
808         DPL::OptionalString m_name;
809         DPL::OptionalString m_value;
810         ConfigParserData::Feature& m_data;
811     };
812
813     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
814             const DPL::String& name)
815     {
816         if (name == L"param") {
817             return DPL::MakeDelegate(this, &FeatureParser::OnParamElement);
818         } else {
819             return &IgnoringParser::Create;
820         }
821     }
822
823     virtual void Accept(const Text& /*text*/)
824     {
825     }
826
827     virtual void Accept(const Element& /*element*/)
828     {
829     }
830
831     virtual void Accept(const XmlAttribute& attribute)
832     {
833         if (attribute.name == L"name") {
834             m_feature.name = attribute.value;
835         } else if (attribute.name == L"required") {
836             if (attribute.value == L"false") {
837                 m_feature.required = false;
838             } else {
839                 m_feature.required = true;
840             }
841         }
842     }
843
844     virtual void Verify()
845     {
846         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
847
848         if (m_feature.name != L"") {
849             if (iri.Validate()) {
850                 if (m_data.featuresList.find(m_feature) ==
851                     m_data.featuresList.end()) {
852                     m_data.featuresList.insert(m_feature);
853                 } else {
854                     LogDebug("Ignoring feature with name" <<
855                              DPL::ToUTF8String(m_feature.name));
856                 }
857             } else {
858                 if (m_feature.required) {
859                     //Throw only if required
860                     ThrowMsg(Exception::ParseError, "invalid feature IRI");
861                 }
862             }
863         }
864     }
865
866     ElementParserPtr OnParamElement()
867     {
868         return ElementParserPtr(new ParamParser(m_feature));
869     }
870
871     FeatureParser(ConfigParserData& data) :
872         ElementParser(),
873         m_data(data),
874         m_feature(L"")
875     {
876     }
877
878   private:
879     ConfigParserData& m_data;
880     ConfigParserData::Feature m_feature;
881 };
882
883 class PreferenceParser : public ElementParser
884 {
885   public:
886     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
887             const DPL::String& /*name*/)
888     {
889         return &IgnoringParser::Create;
890     }
891
892     virtual void Accept(const XmlAttribute& attribute)
893     {
894         if (attribute.name == L"name") {
895             m_name = attribute.value;
896         } else if (attribute.name == L"value") {
897             m_value = attribute.value;
898         } else if (attribute.name == L"readonly") {
899             if (attribute.value == L"true") {
900                 m_required = true;
901             } else {
902                 m_required = false;
903             }
904         }
905     }
906
907     virtual void Accept(const Element& /*element*/)
908     {
909     }
910
911     virtual void Accept(const Text& /*text*/)
912     {
913         ThrowMsg(Exception::ParseError, "param element must be empty");
914     }
915
916     virtual void Verify()
917     {
918         if (m_name.IsNull()) {
919             LogWarning("preference element must have name attribute");
920             return;
921         }
922         NormalizeString(m_name);
923         NormalizeString(m_value);
924         ConfigParserData::Preference preference(*m_name, m_required);
925         preference.value = m_value;
926         if (m_data.preferencesList.find(preference) ==
927             m_data.preferencesList.end()) {
928             m_data.preferencesList.insert(preference);
929         }
930     }
931
932     PreferenceParser(ConfigParserData& data) :
933         ElementParser(),
934         m_required(false),
935         m_data(data)
936     {
937     }
938
939   private:
940     DPL::OptionalString m_name;
941     DPL::OptionalString m_value;
942     bool m_required;
943     ConfigParserData& m_data;
944 };
945
946 class LinkParser : public ElementParser
947 {
948   public:
949     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
950             const DPL::String& /*name*/)
951     {
952         return &DenyAllParser::Create;
953     }
954
955     virtual void Accept(const XmlAttribute& attribute)
956     {
957         if (m_properNamespace) {
958             LogDebug("attribute");
959             if (attribute.name == L"rel") {
960                 if (attribute.value != L"describedby") {
961                     ThrowMsg(Exception::ParseError,
962                              "rel attribute must have describedby value");
963                 }
964             } else if (attribute.name == L"type") {
965             } else if (attribute.name == L"href") {
966                 LogDebug("here is href");
967                 m_href = attribute.value;
968             } else {
969                 ThrowMsg(Exception::ParseError,
970                          "unknown attribute '" +
971                          DPL::ToUTF8String(attribute.name) +
972                          "' in link element");
973             }
974         }
975     }
976
977     virtual void Accept(const Element& element)
978     {
979         if (element.ns ==
980             ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement)
981         {
982             m_properNamespace = true;
983         }
984         LogDebug("element");
985     }
986
987     virtual void Accept(const Text&)
988     {
989         if (m_properNamespace) {
990             LogDebug("text");
991             ThrowMsg(Exception::ParseError, "link element must be empty");
992         }
993     }
994
995     virtual void Verify()
996     {
997         if (!m_href) {
998             ThrowMsg(Exception::ParseError,
999                      "link element must have href attribute");
1000         }
1001
1002         LibIri::Wrapper iri(DPL::ToUTF8String(*m_href).c_str());
1003         if (!iri.Validate()) { // TODO: Better uri validator ?
1004             ThrowMsg(Exception::ParseError,
1005                      "href attribute must be a valid iri/uri/url");
1006         }
1007     }
1008
1009     LinkParser(ConfigParserData& data) :
1010         ElementParser(),
1011         m_properNamespace(false),
1012         m_data(data),
1013         m_href(DPL::OptionalString::Null)
1014     {
1015     }
1016
1017   private:
1018     bool m_properNamespace;
1019     ConfigParserData& m_data;
1020     DPL::OptionalString m_href;
1021 };
1022
1023 class SettingParser : public ElementParser
1024 {
1025   public:
1026     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1027             const DPL::String& /*name*/)
1028     {
1029         return &IgnoringParser::Create;
1030     }
1031
1032     virtual void Accept(const Text& /*text*/)
1033     {
1034     }
1035
1036     virtual void Accept(const Element& /*element*/)
1037     {
1038     }
1039
1040     virtual void Accept(const XmlAttribute& attribute)
1041     {
1042         m_setting.m_name = attribute.name;
1043         m_setting.m_value = attribute.value;
1044         m_data.settingsList.insert(m_setting);
1045     }
1046
1047     virtual void Verify()
1048     {
1049     }
1050
1051     SettingParser(ConfigParserData& data) :
1052         ElementParser(),
1053         m_data(data),
1054         m_setting(L"", L"")
1055     {
1056     }
1057
1058   private:
1059     ConfigParserData& m_data;
1060     ConfigParserData::Setting m_setting;
1061 };
1062
1063 class AppControlParser : public ElementParser
1064 {
1065   public:
1066     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1067                                         const DPL::String& /*name*/)
1068     {
1069         return &IgnoringParser::Create;
1070     }
1071
1072     virtual void Accept(const XmlAttribute& attribute)
1073     {
1074         if (attribute.name == L"src") {
1075             m_src = attribute.value;
1076         } else if (attribute.name == L"operation") {
1077             m_operation = attribute.value;
1078         } else if (attribute.name == L"scheme") {
1079             m_scheme = attribute.value;
1080         } else if (attribute.name == L"mime") {
1081             m_mime = attribute.value;
1082         }
1083     }
1084
1085     virtual void Accept(const Element& element)
1086     {
1087         LogWarning("namespace for app service = " << element.ns);
1088         if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1089             ThrowMsg(Exception::ParseError,
1090                 "Wrong xml namespace for widget element");
1091         }
1092     }
1093
1094     virtual void Accept(const Text& /*text*/)
1095     {
1096         ThrowMsg(Exception::ParseError, "param element must be empty");
1097     }
1098
1099     virtual void Verify()
1100     {
1101         if (m_src.IsNull()) {
1102             LogWarning("service element must have target attribute");
1103             return;
1104         } else if (m_operation.IsNull()) {
1105             LogWarning("service element must have operation attribute");
1106             return;
1107         }
1108         NormalizeString(m_src);
1109         NormalizeString(m_operation);
1110         NormalizeString(m_scheme);
1111         NormalizeString(m_mime);
1112
1113         // verify duplicate element
1114         DPL::String wildString(L"*/*");
1115         DPL::String nullString(L"");
1116         ConfigParserData::ServiceInfo serviceInfo(
1117             m_src.IsNull()       ? nullString:*m_src,
1118             m_operation.IsNull() ? nullString:*m_operation,
1119             m_scheme.IsNull()    ? nullString:*m_scheme,
1120             m_mime.IsNull()      ? nullString:*m_mime);
1121
1122         FOREACH(iterator, m_data.appServiceList) {
1123             if (iterator->m_operation == serviceInfo.m_operation &&
1124                 // check scheme
1125                 (iterator->m_scheme == serviceInfo.m_scheme ||
1126                 // check input scheme is "*/*" case
1127                 (iterator->m_scheme == wildString &&
1128                  serviceInfo.m_scheme != nullString) ||
1129                 // check iterator scheme is "*/*" case
1130                 (serviceInfo.m_scheme == wildString &&
1131                  iterator->m_scheme != nullString)) &&
1132
1133                 (iterator->m_mime == serviceInfo.m_mime ||
1134                 // check input mime is "*/*" case
1135                 (iterator->m_mime == wildString &&
1136                  serviceInfo.m_mime != nullString) ||
1137                 // check iterator mime is "*/*" case
1138                 (serviceInfo.m_mime == wildString &&
1139                  iterator->m_mime != nullString)))
1140             {
1141                 ThrowMsg(Exception::ParseError,
1142                     "service operation is duplicated " +
1143                     DPL::ToUTF8String(*m_operation));
1144             }
1145         }
1146         m_data.appServiceList.push_back(serviceInfo);
1147     }
1148
1149     AppControlParser(ConfigParserData& data) :
1150         ElementParser(),
1151         m_src(DPL::OptionalString::Null),
1152         m_operation(DPL::OptionalString::Null),
1153         m_scheme(DPL::OptionalString::Null),
1154         m_mime(DPL::OptionalString::Null),
1155         m_data(data)
1156     {
1157     }
1158
1159   private:
1160     DPL::OptionalString m_src;
1161     DPL::OptionalString m_operation;
1162     DPL::OptionalString m_scheme;
1163     DPL::OptionalString m_mime;
1164     ConfigParserData& m_data;
1165 };
1166
1167 class ApplicationParser : public ElementParser
1168 {
1169   public:
1170     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1171             const DPL::String& /*name*/)
1172     {
1173         return &IgnoringParser::Create;
1174     }
1175
1176     virtual void Accept(const Text& text)
1177     {
1178         if (m_properNamespace) {
1179             LogDebug("text");
1180             ThrowMsg(Exception::ParseError, "application element must be empty");
1181         }
1182     }
1183
1184     virtual void Accept(const Element& element)
1185     {
1186         if (element.ns ==
1187             ConfigurationNamespace::TizenWebAppNamespaceName)
1188         {
1189             m_properNamespace = true;
1190         }
1191         LogDebug("element");
1192     }
1193
1194     virtual void Accept(const XmlAttribute& attribute)
1195     {
1196         if (m_properNamespace) {
1197             LogDebug("attribute");
1198             if (attribute.name == L"id") {
1199                 m_id = attribute.value;
1200             } else if (attribute.name == L"required_version") {
1201                 m_version = attribute.value;
1202                 NormalizeString(m_version);
1203             } else {
1204                 ThrowMsg(Exception::ParseError,
1205                          "unknown attribute '" +
1206                          DPL::ToUTF8String(attribute.name) +
1207                          "' in application element");
1208             }
1209         }
1210     }
1211
1212     virtual void Verify()
1213     {
1214         if(!m_id) {
1215             ThrowMsg(Exception::ParseError,
1216                      "application element must have id attribute");
1217         }
1218
1219         if(!m_version) {
1220             ThrowMsg(Exception::ParseError,
1221                      "application element must have required_version attribute");
1222         }
1223
1224         //TODO check if id and version format is right
1225         m_data.tizenId = m_id;
1226         m_data.tizenMinVersionRequired = m_version;
1227     }
1228
1229     ApplicationParser(ConfigParserData& data) :
1230         ElementParser(),
1231         m_data(data),
1232         m_id(DPL::OptionalString::Null),
1233         m_version(DPL::OptionalString::Null),
1234         m_properNamespace(false)
1235     {
1236     }
1237
1238   private:
1239     ConfigParserData& m_data;
1240     DPL::OptionalString m_id;
1241     DPL::OptionalString m_version;
1242     bool m_properNamespace;
1243 };
1244
1245 class SplashParser : public ElementParser
1246 {
1247   public:
1248     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1249                                         const DPL::String& /*name*/)
1250     {
1251         return &IgnoringParser::Create;
1252     }
1253
1254     virtual void Accept(const XmlAttribute& attribute)
1255     {
1256         if (attribute.name == L"src") {
1257             if (attribute.value.size() > 0) {
1258                 m_src = attribute.value;
1259             }
1260         }
1261     }
1262
1263     virtual void Accept(const Element& element)
1264     {
1265     }
1266
1267     virtual void Accept(const Text& /*text*/)
1268     {
1269     }
1270
1271     virtual void Verify()
1272     {
1273         if (m_src.IsNull()) {
1274             LogWarning("src attribute of splash element is mandatory - ignoring");
1275             return;
1276         }
1277
1278         m_data.splashImgSrc = m_src;
1279     }
1280
1281     SplashParser(ConfigParserData& data) :
1282         ElementParser(),
1283         m_data(data)
1284     {
1285     }
1286
1287   private:
1288     DPL::OptionalString m_src;
1289     ConfigParserData& m_data;
1290 };
1291
1292 class BackgroundParser : public ElementParser
1293 {
1294   public:
1295     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1296                                         const DPL::String& /*name*/)
1297     {
1298         return &IgnoringParser::Create;
1299     }
1300
1301     virtual void Accept(const XmlAttribute& attribute)
1302     {
1303         if (attribute.name == L"src") {
1304             if (attribute.value.size() > 0) {
1305                 m_src = attribute.value;
1306             }
1307         }
1308     }
1309
1310     virtual void Accept(const Element& /*element*/)
1311     {
1312     }
1313
1314     virtual void Accept(const Text& /*text*/)
1315     {
1316     }
1317
1318     virtual void Verify()
1319     {
1320         if (m_src.IsNull()) {
1321             LogWarning("src attribute of background element is mandatory - ignoring");
1322             return;
1323         }
1324
1325         m_data.backgroundPage = m_src;
1326     }
1327
1328     explicit BackgroundParser(ConfigParserData& data) :
1329         m_data(data)
1330     {
1331     }
1332
1333   private:
1334     DPL::OptionalString m_src;
1335     ConfigParserData& m_data;
1336 };
1337
1338 class PrivilegeParser : public ElementParser
1339 {
1340   public:
1341     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1342             const DPL::String& name)
1343     {
1344         return &IgnoringParser::Create;
1345     }
1346
1347     virtual void Accept(const Text& /*text*/)
1348     {
1349     }
1350
1351     virtual void Accept(const Element& element)
1352     {
1353         if (element.ns ==
1354             ConfigurationNamespace::TizenWebAppNamespaceName)
1355         {
1356             m_properNamespace = true;
1357         }
1358         LogDebug("element");
1359     }
1360
1361     virtual void Accept(const XmlAttribute& attribute)
1362     {
1363         if (m_properNamespace) {
1364             if (attribute.name == L"name") {
1365                 m_feature.name = attribute.value;
1366                 m_privilege.name = attribute.value;
1367             }
1368         }
1369         m_feature.required = true;
1370     }
1371
1372     virtual void Verify()
1373     {
1374         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1375
1376         if (m_feature.name != L"") {
1377             if (iri.Validate()) {
1378                 if (m_data.featuresList.find(m_feature) ==
1379                     m_data.featuresList.end()) {
1380                     m_data.featuresList.insert(m_feature);
1381                 } else {
1382                     LogDebug("Ignoring feature with name" <<
1383                              DPL::ToUTF8String(m_feature.name));
1384                 }
1385             }
1386         }
1387
1388         LibIri::Wrapper iriPrivilege(
1389             DPL::ToUTF8String(m_privilege.name).c_str());
1390
1391         if (m_privilege.name != L"") {
1392             if (iriPrivilege.Validate()) {
1393                 if (m_data.privilegeList.find(m_privilege) ==
1394                     m_data.privilegeList.end()) {
1395                     m_data.privilegeList.insert(m_privilege);
1396                 } else {
1397                     LogDebug("Ignoring privilege with name" <<
1398                              DPL::ToUTF8String(m_privilege.name));
1399                 }
1400             }
1401         }
1402     }
1403
1404     PrivilegeParser(ConfigParserData& data) :
1405         ElementParser(),
1406         m_data(data),
1407         m_feature(L""),
1408         m_privilege(L""),
1409         m_properNamespace(false)
1410     {
1411     }
1412
1413   private:
1414     ConfigParserData& m_data;
1415     ConfigParserData::Feature m_feature;
1416     ConfigParserData::Privilege m_privilege;
1417     bool m_properNamespace;
1418 };
1419
1420 class CategoryParser : public ElementParser
1421 {
1422   public:
1423     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1424                                         const DPL::String& /*name*/)
1425     {
1426         return &IgnoringParser::Create;
1427     }
1428
1429     virtual void Accept(const XmlAttribute& attribute)
1430     {
1431         if (attribute.name == L"name") {
1432             if (attribute.value.size() > 0) {
1433                 m_name = attribute.value;
1434             }
1435         }
1436     }
1437
1438     virtual void Accept(const Element& /*element*/)
1439     {
1440     }
1441
1442     virtual void Accept(const Text& /*text*/)
1443     {
1444     }
1445
1446     virtual void Verify()
1447     {
1448         if (m_name.IsNull()) {
1449             LogWarning("name attribute of category element is mandatory - ignoring");
1450             return;
1451         }
1452
1453         if (m_data.categoryList.find(*m_name) ==
1454             m_data.categoryList.end()) {
1455             m_data.categoryList.insert(*m_name);
1456         }
1457     }
1458
1459     explicit CategoryParser(ConfigParserData& data) :
1460         m_data(data)
1461     {
1462     }
1463
1464   private:
1465     DPL::OptionalString m_name;
1466     ConfigParserData& m_data;
1467 };
1468
1469 class LiveboxParser : public ElementParser
1470 {
1471     public:
1472
1473     struct BoxLabelParser : public ElementParser
1474     {
1475         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1476                 const DPL::String& /*name*/)
1477         {
1478             return &IgnoringParser::Create;
1479         }
1480
1481         virtual void Accept(const XmlAttribute& attribute)
1482         {
1483         }
1484
1485         virtual void Accept(const Element& element)
1486         {
1487             if (element.ns ==
1488                     ConfigurationNamespace::TizenWebAppNamespaceName)
1489             {
1490                 m_properNamespace = true;
1491             }
1492         }
1493
1494         virtual void Accept(const Text& text)
1495         {
1496             if(m_properNamespace)
1497                 m_label = text.value;
1498         }
1499
1500         virtual void Verify()
1501         {
1502             m_data.m_label = m_label;
1503         }
1504
1505         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1506             ElementParser(),
1507             m_properNamespace(false),
1508             m_data(data)
1509         {
1510         }
1511
1512         private:
1513         DPL::String m_label;
1514         bool m_properNamespace;
1515         ConfigParserData::LiveboxInfo& m_data;
1516     };
1517
1518     struct BoxIconParser : public ElementParser
1519     {
1520         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1521                 const DPL::String& /*name*/)
1522         {
1523             return &IgnoringParser::Create;
1524         }
1525
1526         virtual void Accept(const XmlAttribute& attribute)
1527         {
1528             if(m_properNamespace) {
1529                 if (attribute.name == L"src") {
1530                     m_icon = attribute.value;
1531                 }
1532             }
1533         }
1534
1535         virtual void Accept(const Element& element)
1536         {
1537             if (element.ns ==
1538                     ConfigurationNamespace::TizenWebAppNamespaceName)
1539             {
1540                 m_properNamespace = true;
1541             }
1542         }
1543
1544         virtual void Accept(const Text& /*text*/)
1545         {
1546         }
1547
1548         virtual void Verify()
1549         {
1550             m_data.m_icon = m_icon;
1551         }
1552
1553         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1554             ElementParser(),
1555             m_properNamespace(false),
1556             m_data(data)
1557         {
1558         }
1559
1560         private:
1561         DPL::String m_icon;
1562         bool m_properNamespace;
1563         ConfigParserData::LiveboxInfo& m_data;
1564     };
1565
1566     struct BoxContentParser : public ElementParser
1567     {
1568         struct BoxSizeParser : public ElementParser
1569         {
1570             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1571                     const DPL::String& /*name*/)
1572             {
1573                 return &IgnoringParser::Create;
1574             }
1575
1576             virtual void Accept(const XmlAttribute& attribute)
1577             {
1578                 if(m_properNamespace) {
1579                     if (attribute.name == L"preview") {
1580                         m_preview = attribute.value;
1581                     }
1582                 }
1583             }
1584
1585             virtual void Accept(const Element& element)
1586             {
1587                 if (element.ns ==
1588                         ConfigurationNamespace::TizenWebAppNamespaceName)
1589                 {
1590                     m_properNamespace = true;
1591                 }
1592             }
1593
1594             virtual void Accept(const Text& text)
1595             {
1596                 if(m_properNamespace)
1597                     m_size = text.value;
1598             }
1599
1600             virtual void Verify()
1601             {
1602                 std::pair<DPL::String, DPL::String> boxSize;
1603                 boxSize.first = m_size;
1604                 boxSize.second = m_preview;
1605                 m_data.m_boxSize.push_back(boxSize);
1606             }
1607
1608             explicit BoxSizeParser(ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1609                 ElementParser(),
1610                 m_data(data)
1611             {
1612             }
1613
1614             private:
1615             DPL::String m_size;
1616             DPL::String m_preview;
1617             bool m_properNamespace;
1618             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1619         };
1620
1621         struct PdParser : public ElementParser
1622         {
1623             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1624                     const DPL::String& name)
1625             {
1626                 return &IgnoringParser::Create;
1627             }
1628
1629             virtual void Accept(const XmlAttribute& attribute)
1630             {
1631                 if(m_properNamespace) {
1632                     if (attribute.name == L"src") {
1633                         m_src = attribute.value;
1634                     } else if (attribute.name == L"width") {
1635                         m_width = attribute.value;
1636                     } else if (attribute.name == L"height") {
1637                         m_height = attribute.value;
1638                     }
1639                 }
1640             }
1641
1642             virtual void Accept(const Element& element)
1643             {
1644                 if (element.ns ==
1645                         ConfigurationNamespace::TizenWebAppNamespaceName)
1646                 {
1647                     m_properNamespace = true;
1648                 }
1649             }
1650
1651             virtual void Accept(const Text& /*text*/)
1652             {
1653             }
1654
1655             virtual void Verify()
1656             {
1657                 m_data.m_pdSrc = m_src;
1658                 m_data.m_pdWidth = m_width;
1659                 m_data.m_pdHeight = m_height;
1660             }
1661
1662             explicit PdParser(ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1663                 ElementParser(),
1664                 m_properNamespace(false),
1665                 m_data(data)
1666             {
1667             }
1668
1669             private:
1670             DPL::String m_src;
1671             DPL::String m_width;
1672             DPL::String m_height;
1673
1674             bool m_properNamespace;
1675             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1676         };
1677
1678         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1679                 const DPL::String& name)
1680         {
1681             if (name == L"box-size") {
1682                 return DPL::MakeDelegate(this, &LiveboxParser::BoxContentParser::OnBoxSizeElement);
1683             } else if (name == L"pd") {
1684                 return DPL::MakeDelegate(this, &LiveboxParser::BoxContentParser::OnPdElement);
1685             } else{
1686                 ThrowMsg(Exception::ParseError, "No element parser for name: " << name);
1687             }
1688         }
1689
1690         virtual void Accept(const XmlAttribute& attribute)
1691         {
1692             if (m_properNamespace) {
1693                 if (attribute.name == L"src")
1694                     m_box.m_boxSrc = attribute.value;
1695             }
1696         }
1697
1698         virtual void Accept(const Element& element)
1699         {
1700             if (element.ns ==
1701                     ConfigurationNamespace::TizenWebAppNamespaceName)
1702             {
1703                 m_properNamespace = true;
1704             }
1705         }
1706
1707         virtual void Accept(const Text& /*text*/)
1708         {
1709         }
1710
1711         virtual void Verify()
1712         {
1713             m_data.m_boxInfo = m_box;
1714         }
1715
1716         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1717             ElementParser(),
1718             m_properNamespace(false),
1719             m_data(data)
1720         {
1721         }
1722
1723         ElementParserPtr OnBoxSizeElement()
1724         {
1725             return ElementParserPtr(new BoxSizeParser(m_box));
1726         }
1727
1728         ElementParserPtr OnPdElement()
1729         {
1730             return ElementParserPtr(new PdParser(m_box));
1731         }
1732
1733         private:
1734         DPL::String m_src;
1735         bool m_properNamespace;
1736         ConfigParserData::LiveboxInfo& m_data;
1737         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1738     };
1739
1740     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1741             const DPL::String& name)
1742     {
1743         if (name == L"box-label") {
1744             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxLabelElement);
1745         } else if (name == L"box-icon") {
1746             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxIconElement);
1747         }  else if (name == L"box-content") {
1748             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxContentElement);
1749         } else {
1750             return &IgnoringParser::Create;
1751         }
1752     }
1753
1754     virtual void Accept(const XmlAttribute& attribute)
1755     {
1756         if (m_properNamespace) {
1757             if (attribute.name == L"id") {
1758                 m_liveboxId = attribute.value;
1759             } else if (attribute.name == L"primary") {
1760                 m_primary = attribute.value;
1761             } else if (attribute.name == L"auto-launch") {
1762                 m_autoLaunch = attribute.value;
1763             } else if (attribute.name == L"update-period") {
1764                 m_updatePeriod = attribute.value;
1765             }
1766         }
1767     }
1768
1769     virtual void Accept(const Element& element)
1770     {
1771         if (element.ns ==
1772                 ConfigurationNamespace::TizenWebAppNamespaceName)
1773         {
1774             m_properNamespace = true;
1775         }
1776     }
1777
1778     virtual void Accept(const Text& /*text*/)
1779     {
1780     }
1781
1782     virtual void Verify()
1783     {
1784         m_livebox.m_liveboxId = m_liveboxId;
1785         m_livebox.m_primary = m_primary;
1786         m_livebox.m_autoLaunch = m_autoLaunch;
1787         m_livebox.m_updatePeriod = m_updatePeriod;
1788
1789         m_data.m_livebox.push_back(m_livebox);
1790     }
1791
1792     explicit LiveboxParser(ConfigParserData& data) :
1793         ElementParser(),
1794         m_data(data),
1795         m_properNamespace(false)
1796     {
1797         m_livebox = ConfigParserData::LiveboxInfo();
1798     }
1799
1800     ElementParserPtr OnBoxLabelElement()
1801     {
1802         return ElementParserPtr(new BoxLabelParser(m_livebox));
1803     }
1804
1805     ElementParserPtr OnBoxIconElement()
1806     {
1807         return ElementParserPtr(new BoxIconParser(m_livebox));
1808     }
1809
1810     ElementParserPtr OnBoxContentElement()
1811     {
1812         return ElementParserPtr(new BoxContentParser(m_livebox));
1813     }
1814
1815   private:
1816     ConfigParserData& m_data;
1817     ConfigParserData::LiveboxInfo m_livebox;
1818     DPL::String m_liveboxId;
1819     DPL::String m_primary;
1820     DPL::String m_autoLaunch;
1821     DPL::String m_updatePeriod;
1822     bool m_properNamespace;
1823
1824 };
1825
1826 ElementParser::ActionFunc WidgetParser::GetElementParser(const DPL::String& /*ns*/,
1827         const DPL::String& name)
1828 {
1829     FuncMap::const_iterator it = m_map.find(name);
1830     if (it != m_map.end()) {
1831         return it->second;
1832     } else {
1833         return &IgnoringParser::Create;
1834     }
1835 }
1836
1837 WidgetParser::WidgetParser(ConfigParserData& data) :
1838     m_data(data),
1839     m_textDirection(Unicode::EMPTY)
1840 {
1841     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
1842     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
1843     m_map[L"description"] =
1844         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
1845     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
1846     m_map[L"license"] =
1847         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
1848     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
1849     m_map[L"content"] =
1850         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
1851     m_map[L"feature"] =
1852         DPL::MakeDelegate(this, &WidgetParser::OnFeatureElement);
1853     m_map[L"preference"] =
1854         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
1855     m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement);
1856     m_map[L"setting"] =
1857         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
1858     // TODO: appservice will be removed
1859     m_map[L"appservice"] = DPL::MakeDelegate(this, &WidgetParser::OnAppControlElement);
1860     m_map[L"application"] = DPL::MakeDelegate(this, &WidgetParser::OnApplicationElement);
1861     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
1862     m_map[L"background"] = DPL::MakeDelegate(this, &WidgetParser::OnBackgroundElement);
1863     m_map[L"privilege"] = DPL::MakeDelegate(this, &WidgetParser::OnPrivilegeElement);
1864     m_map[L"appcontrol"] = DPL::MakeDelegate(this,
1865             &WidgetParser::OnAppControlElement);
1866     m_map[L"category"] = DPL::MakeDelegate(this,
1867             &WidgetParser::OnCategoryElement);
1868     m_map[L"livebox"] = DPL::MakeDelegate(this, &WidgetParser::OnLiveboxElement);
1869
1870 }
1871
1872 ElementParserPtr WidgetParser::OnNameElement()
1873 {
1874     return ElementParserPtr(new NameParser(m_textDirection, m_data));
1875 }
1876
1877 ElementParserPtr WidgetParser::OnAccessElement()
1878 {
1879     return ElementParserPtr(new AccessParser(m_data));
1880 }
1881
1882 ElementParserPtr WidgetParser::OnDescriptionElement()
1883 {
1884     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
1885 }
1886
1887 ElementParserPtr WidgetParser::OnAuthorElement()
1888 {
1889     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
1890 }
1891
1892 ElementParserPtr WidgetParser::OnLicenseElement()
1893 {
1894     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
1895 }
1896
1897 ElementParserPtr WidgetParser::OnIconElement()
1898 {
1899     return ElementParserPtr(new IconParser(m_data));
1900 }
1901
1902 ElementParserPtr WidgetParser::OnContentElement()
1903 {
1904     return ElementParserPtr(new ContentParser(m_data));
1905 }
1906
1907 ElementParserPtr WidgetParser::OnFeatureElement()
1908 {
1909     return ElementParserPtr(new FeatureParser(m_data));
1910 }
1911
1912 ElementParserPtr WidgetParser::OnPreferenceElement()
1913 {
1914     return ElementParserPtr(new PreferenceParser(m_data));
1915 }
1916
1917 ElementParserPtr WidgetParser::OnLinkElement()
1918 {
1919     return ElementParserPtr(new LinkParser(m_data));
1920 }
1921
1922 ElementParserPtr WidgetParser::OnSettingElement()
1923 {
1924     return ElementParserPtr(new SettingParser(m_data));
1925 }
1926
1927 ElementParserPtr WidgetParser::OnApplicationElement()
1928 {
1929     return ElementParserPtr(new ApplicationParser(m_data));
1930 }
1931
1932 ElementParserPtr WidgetParser::OnSplashElement()
1933 {
1934     return ElementParserPtr(new SplashParser(m_data));
1935 }
1936
1937 ElementParserPtr WidgetParser::OnBackgroundElement()
1938 {
1939     return ElementParserPtr(new BackgroundParser(m_data));
1940 }
1941
1942 ElementParserPtr WidgetParser::OnPrivilegeElement()
1943 {
1944     return ElementParserPtr(new PrivilegeParser(m_data));
1945 }
1946
1947 ElementParserPtr WidgetParser::OnAppControlElement()
1948 {
1949     return ElementParserPtr(new AppControlParser(m_data));
1950 }
1951
1952 ElementParserPtr WidgetParser::OnCategoryElement()
1953 {
1954     return ElementParserPtr(new CategoryParser(m_data));
1955 }
1956
1957 ElementParserPtr WidgetParser::OnLiveboxElement()
1958 {
1959     return ElementParserPtr(new LiveboxParser(m_data));
1960 }
1961
1962 void WidgetParser::Accept(const Element& element)
1963 {
1964     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
1965         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
1966     {
1967         ThrowMsg(Exception::ParseError,
1968                  "Wrong xml namespace for widget element");
1969     }
1970 }
1971
1972 void WidgetParser::Accept(const Text& /*text*/)
1973 {
1974     ThrowMsg(Exception::ParseError, "widged element must be empty");
1975 }
1976
1977 void WidgetParser::Accept(const XmlAttribute& attribute)
1978 {
1979     if (attribute.name == L"id") {
1980         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
1981         //If may important tests starts to fail this test we will have
1982         //to consider commenting this test out again.
1983         if (iri.Validate()) {
1984             m_data.widget_id = attribute.value;
1985             NormalizeString(m_data.widget_id);
1986         } else {
1987             LogWarning("Widget id validation failed: " << attribute.value);
1988         }
1989     } else if (attribute.name == L"version") {
1990         m_version = attribute.value;
1991         NormalizeString(m_version);
1992     } else if (attribute.name == L"min-version") {
1993         LogInfo("min-version attribute was found. Value: " << attribute.value);
1994         m_minVersion = attribute.value;
1995         NormalizeString(m_minVersion);
1996         m_data.minVersionRequired = m_minVersion;
1997     } else if (attribute.name == L"height") {
1998         DPL::OptionalString value = attribute.value;
1999         NormalizeString(value);
2000         std::string v = DPL::ToUTF8String(*value);
2001
2002         if (!v.empty()) {
2003             unsigned char c = v.c_str()[0];
2004             if (c >= '0' && c <= '9') {
2005                 int val = 0;
2006                 for (size_t i = 0; i < v.size(); ++i) {
2007                     c = v.c_str()[i];
2008                     if (c >= '0' && c <= '9') {
2009                         val *= 10;
2010                         val += (c - '0');
2011                     } else {
2012                         break;
2013                     }
2014                 }
2015                 m_data.height = val;
2016             }
2017         }
2018     } else if (attribute.name == L"width") {
2019         DPL::OptionalString value = attribute.value;
2020         NormalizeString(value);
2021         std::string v = DPL::ToUTF8String(*value);
2022
2023         if (!v.empty()) {
2024             unsigned char c = v.c_str()[0];
2025             if (c >= '0' && c <= '9') {
2026                 int val = 0;
2027                 for (size_t i = 0; i < v.size(); ++i) {
2028                     c = v.c_str()[i];
2029                     if (c >= '0' && c <= '9') {
2030                         val *= 10;
2031                         val += (c - '0');
2032                     } else {
2033                         break;
2034                     }
2035                 }
2036                 m_data.width = val;
2037             }
2038         }
2039     } else if (attribute.name == L"viewmodes") {
2040         DPL::Tokenize(attribute.value,
2041                       L" ",
2042                       std::inserter(m_windowModes,
2043                                     m_windowModes.end()),
2044                       true);
2045     } else if (attribute.name == L"dir") {
2046         m_textDirection = Unicode::ParseDirAttribute(attribute);
2047     } else if (L"defaultlocale" == attribute.name) {
2048         if (!m_defaultlocale) {
2049             m_defaultlocale = attribute.value;
2050             NormalizeString(m_defaultlocale);
2051             if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag(
2052                     DPL::ToUTF8String(*m_defaultlocale))) {
2053                 LogWarning("Language tag: " <<
2054                            m_defaultlocale << " is not valid");
2055                 m_defaultlocale = DPL::OptionalString::Null;
2056             }
2057             else
2058                 LogDebug("Default Locale Found " << m_defaultlocale);
2059         } else {
2060             LogWarning("Ignoring subsequent default locale");
2061         }
2062
2063     //Any other value consider as a namespace definition
2064     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2065         LogInfo("Namespace domain: " << attribute.name);
2066         LogInfo("Namespace value: " << attribute.value);
2067         m_nameSpaces[attribute.name] = attribute.value;
2068     } else {
2069         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2070                 ", name=" << attribute.name <<
2071                 ", value=" << attribute.value);
2072     }
2073 }
2074
2075 void WidgetParser::Verify()
2076 {
2077     FOREACH(mode, m_windowModes) {
2078         if (L"windowed" == *mode || L"floating" == *mode ||
2079             L"fullscreen" == *mode || L"maximized" == *mode ||
2080             L"minimized" == *mode) {
2081             m_data.windowModes.insert(*mode);
2082         }
2083     }
2084     if (!m_version.IsNull()) {
2085         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2086         m_data.version = m_version;
2087     }
2088     m_data.defaultlocale = m_defaultlocale;
2089     FOREACH(ns, m_nameSpaces) {
2090         m_data.nameSpaces.insert(ns->second);
2091     }
2092 }
2093