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