Revert "Support mouse-event of <tizen:box-content> and type of <tizen:livebox>"
[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                 NormalizeAndTrimSpaceString(m_id);
1510             } else if (attribute.name == L"package") {
1511                 m_package = attribute.value;
1512             } else if (attribute.name == L"required_version") {
1513                 m_version = attribute.value;
1514                 NormalizeString(m_version);
1515             } else {
1516                 ThrowMsg(Exception::ParseError,
1517                          "unknown attribute '" +
1518                          DPL::ToUTF8String(attribute.name) +
1519                          "' in application element");
1520             }
1521         }
1522     }
1523
1524     virtual void Verify()
1525     {
1526         if(!m_id) {
1527             ThrowMsg(Exception::ParseError,
1528                      "application element must have id attribute");
1529         }
1530
1531         if(!!m_package) {
1532             m_data.tizenPkgId = m_package;
1533         }
1534
1535         if(!m_version) {
1536             ThrowMsg(Exception::ParseError,
1537                      "application element must have required_version attribute");
1538         }
1539
1540         //TODO check if id and version format is right
1541         m_data.tizenAppId = m_id;
1542         m_data.tizenMinVersionRequired = m_version;
1543     }
1544
1545     ApplicationParser(ConfigParserData& data) :
1546         ElementParser(),
1547         m_data(data),
1548         m_id(DPL::OptionalString::Null),
1549         m_version(DPL::OptionalString::Null),
1550         m_properNamespace(false)
1551     {
1552     }
1553
1554   private:
1555     ConfigParserData& m_data;
1556     DPL::OptionalString m_id;
1557     DPL::OptionalString m_package;
1558     DPL::OptionalString m_version;
1559     bool m_properNamespace;
1560 };
1561
1562 class SplashParser : public ElementParser
1563 {
1564   public:
1565     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1566                                         const DPL::String& /*name*/)
1567     {
1568         return &IgnoringParser::Create;
1569     }
1570
1571     virtual void Accept(const XmlAttribute& attribute)
1572     {
1573         if (attribute.name == L"src") {
1574             if (attribute.value.size() > 0) {
1575                 m_src = attribute.value;
1576             }
1577         }
1578     }
1579
1580     virtual void Accept(const Element& element)
1581     {
1582     }
1583
1584     virtual void Accept(const Text& /*text*/)
1585     {
1586     }
1587
1588     virtual void Verify()
1589     {
1590         if (m_src.IsNull()) {
1591             LogWarning("src attribute of splash element is mandatory - ignoring");
1592             return;
1593         }
1594
1595         m_data.splashImgSrc = m_src;
1596     }
1597
1598     SplashParser(ConfigParserData& data) :
1599         ElementParser(),
1600         m_data(data)
1601     {
1602     }
1603
1604   private:
1605     DPL::OptionalString m_src;
1606     ConfigParserData& m_data;
1607 };
1608
1609 class BackgroundParser : public ElementParser
1610 {
1611   public:
1612     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1613                                         const DPL::String& /*name*/)
1614     {
1615         return &IgnoringParser::Create;
1616     }
1617
1618     virtual void Accept(const XmlAttribute& attribute)
1619     {
1620         if (attribute.name == L"src") {
1621             if (attribute.value.size() > 0) {
1622                 m_src = attribute.value;
1623             }
1624         }
1625     }
1626
1627     virtual void Accept(const Element& /*element*/)
1628     {
1629     }
1630
1631     virtual void Accept(const Text& /*text*/)
1632     {
1633     }
1634
1635     virtual void Verify()
1636     {
1637         if (m_src.IsNull()) {
1638             LogWarning("src attribute of background element is mandatory - ignoring");
1639             return;
1640         }
1641
1642         m_data.backgroundPage = m_src;
1643     }
1644
1645     explicit BackgroundParser(ConfigParserData& data) :
1646         m_data(data)
1647     {
1648     }
1649
1650   private:
1651     DPL::OptionalString m_src;
1652     ConfigParserData& m_data;
1653 };
1654
1655 class PrivilegeParser : public ElementParser
1656 {
1657   public:
1658     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1659             const DPL::String& name)
1660     {
1661         return &IgnoringParser::Create;
1662     }
1663
1664     virtual void Accept(const Text& /*text*/)
1665     {
1666     }
1667
1668     virtual void Accept(const Element& element)
1669     {
1670         if (element.ns ==
1671             ConfigurationNamespace::TizenWebAppNamespaceName)
1672         {
1673             m_properNamespace = true;
1674         }
1675         LogDebug("element");
1676     }
1677
1678     virtual void Accept(const XmlAttribute& attribute)
1679     {
1680         if (m_properNamespace) {
1681             if (attribute.name == L"name") {
1682                 m_feature.name = attribute.value;
1683                 m_privilege.name = attribute.value;
1684             }
1685         }
1686         m_feature.required = false;
1687     }
1688
1689     virtual void Verify()
1690     {
1691         LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1692
1693         if (m_feature.name != L"") {
1694             if (iri.Validate()) {
1695                 if (m_data.featuresList.find(m_feature) ==
1696                     m_data.featuresList.end()) {
1697                     m_data.featuresList.insert(m_feature);
1698                 } else {
1699                     LogDebug("Ignoring feature with name" <<
1700                              DPL::ToUTF8String(m_feature.name));
1701                 }
1702             }
1703         }
1704
1705         LibIri::Wrapper iriPrivilege(
1706             DPL::ToUTF8String(m_privilege.name).c_str());
1707
1708         if (m_privilege.name != L"") {
1709             if (iriPrivilege.Validate()) {
1710                 if (m_data.privilegeList.find(m_privilege) ==
1711                     m_data.privilegeList.end()) {
1712                     m_data.privilegeList.insert(m_privilege);
1713                 } else {
1714                     LogDebug("Ignoring privilege with name" <<
1715                              DPL::ToUTF8String(m_privilege.name));
1716                 }
1717             }
1718         }
1719     }
1720
1721     PrivilegeParser(ConfigParserData& data) :
1722         ElementParser(),
1723         m_data(data),
1724         m_feature(L""),
1725         m_privilege(L""),
1726         m_properNamespace(false)
1727     {
1728     }
1729
1730   private:
1731     ConfigParserData& m_data;
1732     ConfigParserData::Feature m_feature;
1733     ConfigParserData::Privilege m_privilege;
1734     bool m_properNamespace;
1735 };
1736
1737 class CategoryParser : public ElementParser
1738 {
1739   public:
1740     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1741                                         const DPL::String& /*name*/)
1742     {
1743         return &IgnoringParser::Create;
1744     }
1745
1746     virtual void Accept(const XmlAttribute& attribute)
1747     {
1748         if (attribute.name == L"name") {
1749             if (attribute.value.size() > 0) {
1750                 m_name = attribute.value;
1751             }
1752         }
1753     }
1754
1755     virtual void Accept(const Element& /*element*/)
1756     {
1757     }
1758
1759     virtual void Accept(const Text& /*text*/)
1760     {
1761     }
1762
1763     virtual void Verify()
1764     {
1765         if (m_name.IsNull()) {
1766             LogWarning("name attribute of category element is mandatory - ignoring");
1767             return;
1768         }
1769
1770         if (m_data.categoryList.find(*m_name) ==
1771             m_data.categoryList.end()) {
1772             m_data.categoryList.insert(*m_name);
1773         }
1774     }
1775
1776     explicit CategoryParser(ConfigParserData& data) :
1777         m_data(data)
1778     {
1779     }
1780
1781   private:
1782     DPL::OptionalString m_name;
1783     ConfigParserData& m_data;
1784 };
1785
1786 class LiveboxParser : public ElementParser
1787 {
1788     public:
1789
1790     struct BoxLabelParser : public ElementParser
1791     {
1792         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1793                 const DPL::String& /*name*/)
1794         {
1795             return &IgnoringParser::Create;
1796         }
1797
1798         virtual void Accept(const XmlAttribute& attribute)
1799         {
1800         }
1801
1802         virtual void Accept(const Element& element)
1803         {
1804             if (element.ns ==
1805                     ConfigurationNamespace::TizenWebAppNamespaceName)
1806             {
1807                 m_properNamespace = true;
1808             }
1809         }
1810
1811         virtual void Accept(const Text& text)
1812         {
1813             if(m_properNamespace)
1814                 m_label = text.value;
1815         }
1816
1817         virtual void Verify()
1818         {
1819             m_data.m_label = m_label;
1820         }
1821
1822         BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1823             ElementParser(),
1824             m_properNamespace(false),
1825             m_data(data)
1826         {
1827         }
1828
1829         private:
1830         DPL::String m_label;
1831         bool m_properNamespace;
1832         ConfigParserData::LiveboxInfo& m_data;
1833     };
1834
1835     struct BoxIconParser : public ElementParser
1836     {
1837         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1838                 const DPL::String& /*name*/)
1839         {
1840             return &IgnoringParser::Create;
1841         }
1842
1843         virtual void Accept(const XmlAttribute& attribute)
1844         {
1845             if(m_properNamespace) {
1846                 if (attribute.name == L"src") {
1847                     m_icon = attribute.value;
1848                 }
1849             }
1850         }
1851
1852         virtual void Accept(const Element& element)
1853         {
1854             if (element.ns ==
1855                     ConfigurationNamespace::TizenWebAppNamespaceName)
1856             {
1857                 m_properNamespace = true;
1858             }
1859         }
1860
1861         virtual void Accept(const Text& /*text*/)
1862         {
1863         }
1864
1865         virtual void Verify()
1866         {
1867             m_data.m_icon = m_icon;
1868         }
1869
1870         explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1871             ElementParser(),
1872             m_properNamespace(false),
1873             m_data(data)
1874         {
1875         }
1876
1877         private:
1878         DPL::String m_icon;
1879         bool m_properNamespace;
1880         ConfigParserData::LiveboxInfo& m_data;
1881     };
1882
1883     struct BoxContentParser : public ElementParser
1884     {
1885         struct BoxSizeParser : public ElementParser
1886         {
1887             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1888                     const DPL::String& /*name*/)
1889             {
1890                 return &IgnoringParser::Create;
1891             }
1892
1893             virtual void Accept(const XmlAttribute& attribute)
1894             {
1895                 if(m_properNamespace) {
1896                     if (attribute.name == L"preview") {
1897                         m_preview = attribute.value;
1898                     }
1899                 }
1900             }
1901
1902             virtual void Accept(const Element& element)
1903             {
1904                 if (element.ns ==
1905                         ConfigurationNamespace::TizenWebAppNamespaceName)
1906                 {
1907                     m_properNamespace = true;
1908                 }
1909             }
1910
1911             virtual void Accept(const Text& text)
1912             {
1913                 if(m_properNamespace)
1914                     m_size = text.value;
1915             }
1916
1917             virtual void Verify()
1918             {
1919                 std::pair<DPL::String, DPL::String> boxSize;
1920                 boxSize.first = m_size;
1921                 boxSize.second = m_preview;
1922                 m_data.m_boxSize.push_back(boxSize);
1923             }
1924
1925             explicit BoxSizeParser(ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1926                 ElementParser(),
1927                 m_data(data)
1928             {
1929             }
1930
1931             private:
1932             DPL::String m_size;
1933             DPL::String m_preview;
1934             bool m_properNamespace;
1935             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1936         };
1937
1938         struct PdParser : public ElementParser
1939         {
1940             virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1941                     const DPL::String& name)
1942             {
1943                 return &IgnoringParser::Create;
1944             }
1945
1946             virtual void Accept(const XmlAttribute& attribute)
1947             {
1948                 if(m_properNamespace) {
1949                     if (attribute.name == L"src") {
1950                         m_src = attribute.value;
1951                     } else if (attribute.name == L"width") {
1952                         m_width = attribute.value;
1953                     } else if (attribute.name == L"height") {
1954                         m_height = attribute.value;
1955                     }
1956                 }
1957             }
1958
1959             virtual void Accept(const Element& element)
1960             {
1961                 if (element.ns ==
1962                         ConfigurationNamespace::TizenWebAppNamespaceName)
1963                 {
1964                     m_properNamespace = true;
1965                 }
1966             }
1967
1968             virtual void Accept(const Text& /*text*/)
1969             {
1970             }
1971
1972             virtual void Verify()
1973             {
1974                 m_data.m_pdSrc = m_src;
1975                 m_data.m_pdWidth = m_width;
1976                 m_data.m_pdHeight = m_height;
1977             }
1978
1979             explicit PdParser(ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1980                 ElementParser(),
1981                 m_properNamespace(false),
1982                 m_data(data)
1983             {
1984             }
1985
1986             private:
1987             DPL::String m_src;
1988             DPL::String m_width;
1989             DPL::String m_height;
1990
1991             bool m_properNamespace;
1992             ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1993         };
1994
1995         virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1996                 const DPL::String& name)
1997         {
1998             if (name == L"box-size") {
1999                 return DPL::MakeDelegate(this, &LiveboxParser::BoxContentParser::OnBoxSizeElement);
2000             } else if (name == L"pd") {
2001                 return DPL::MakeDelegate(this, &LiveboxParser::BoxContentParser::OnPdElement);
2002             } else{
2003                 ThrowMsg(Exception::ParseError, "No element parser for name: " << name);
2004             }
2005         }
2006
2007         virtual void Accept(const XmlAttribute& attribute)
2008         {
2009             if (m_properNamespace) {
2010                 if (attribute.name == L"src")
2011                     m_box.m_boxSrc = attribute.value;
2012             }
2013         }
2014
2015         virtual void Accept(const Element& element)
2016         {
2017             if (element.ns ==
2018                     ConfigurationNamespace::TizenWebAppNamespaceName)
2019             {
2020                 m_properNamespace = true;
2021             }
2022         }
2023
2024         virtual void Accept(const Text& /*text*/)
2025         {
2026         }
2027
2028         virtual void Verify()
2029         {
2030             m_data.m_boxInfo = m_box;
2031         }
2032
2033         explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
2034             ElementParser(),
2035             m_properNamespace(false),
2036             m_data(data)
2037         {
2038         }
2039
2040         ElementParserPtr OnBoxSizeElement()
2041         {
2042             return ElementParserPtr(new BoxSizeParser(m_box));
2043         }
2044
2045         ElementParserPtr OnPdElement()
2046         {
2047             return ElementParserPtr(new PdParser(m_box));
2048         }
2049
2050         private:
2051         DPL::String m_src;
2052         bool m_properNamespace;
2053         ConfigParserData::LiveboxInfo& m_data;
2054         ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
2055     };
2056
2057     virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2058             const DPL::String& name)
2059     {
2060         if (name == L"box-label") {
2061             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxLabelElement);
2062         } else if (name == L"box-icon") {
2063             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxIconElement);
2064         }  else if (name == L"box-content") {
2065             return DPL::MakeDelegate(this, &LiveboxParser::OnBoxContentElement);
2066         } else {
2067             return &IgnoringParser::Create;
2068         }
2069     }
2070
2071     virtual void Accept(const XmlAttribute& attribute)
2072     {
2073         if (m_properNamespace) {
2074             if (attribute.name == L"id") {
2075                 m_liveboxId = attribute.value;
2076             } else if (attribute.name == L"primary") {
2077                 m_primary = attribute.value;
2078             } else if (attribute.name == L"auto-launch") {
2079                 m_autoLaunch = attribute.value;
2080             } else if (attribute.name == L"update-period") {
2081                 m_updatePeriod = attribute.value;
2082             }
2083         }
2084     }
2085
2086     virtual void Accept(const Element& element)
2087     {
2088         if (element.ns ==
2089                 ConfigurationNamespace::TizenWebAppNamespaceName)
2090         {
2091             m_properNamespace = true;
2092         }
2093     }
2094
2095     virtual void Accept(const Text& /*text*/)
2096     {
2097     }
2098
2099     virtual void Verify()
2100     {
2101         m_livebox.m_liveboxId = m_liveboxId;
2102         m_livebox.m_primary = m_primary;
2103         m_livebox.m_autoLaunch = m_autoLaunch;
2104         m_livebox.m_updatePeriod = m_updatePeriod;
2105
2106         m_data.m_livebox.push_back(m_livebox);
2107     }
2108
2109     explicit LiveboxParser(ConfigParserData& data) :
2110         ElementParser(),
2111         m_data(data),
2112         m_properNamespace(false)
2113     {
2114         m_livebox = ConfigParserData::LiveboxInfo();
2115     }
2116
2117     ElementParserPtr OnBoxLabelElement()
2118     {
2119         return ElementParserPtr(new BoxLabelParser(m_livebox));
2120     }
2121
2122     ElementParserPtr OnBoxIconElement()
2123     {
2124         return ElementParserPtr(new BoxIconParser(m_livebox));
2125     }
2126
2127     ElementParserPtr OnBoxContentElement()
2128     {
2129         return ElementParserPtr(new BoxContentParser(m_livebox));
2130     }
2131
2132   private:
2133     ConfigParserData& m_data;
2134     ConfigParserData::LiveboxInfo m_livebox;
2135     DPL::String m_liveboxId;
2136     DPL::String m_primary;
2137     DPL::String m_autoLaunch;
2138     DPL::String m_updatePeriod;
2139     bool m_properNamespace;
2140
2141 };
2142
2143
2144 ElementParser::ActionFunc WidgetParser::GetElementParser(const DPL::String& /*ns*/,
2145         const DPL::String& name)
2146 {
2147     FuncMap::const_iterator it = m_map.find(name);
2148     if (it != m_map.end()) {
2149         return it->second;
2150     } else {
2151         return &IgnoringParser::Create;
2152     }
2153 }
2154
2155 WidgetParser::WidgetParser(ConfigParserData& data) :
2156     m_data(data),
2157     m_textDirection(Unicode::EMPTY)
2158 {
2159     m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2160     m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2161     m_map[L"description"] =
2162         DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2163     m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2164     m_map[L"license"] =
2165         DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2166     m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2167     m_map[L"content"] =
2168         DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2169     m_map[L"feature"] =
2170         DPL::MakeDelegate(this, &WidgetParser::OnFeatureElement);
2171     m_map[L"preference"] =
2172         DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2173     m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement);
2174     m_map[L"setting"] =
2175         DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2176     // TODO: appservice will be removed
2177     m_map[L"appservice"] = DPL::MakeDelegate(this, &WidgetParser::OnAppServiceElement);
2178     m_map[L"application"] = DPL::MakeDelegate(this, &WidgetParser::OnApplicationElement);
2179     m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2180     m_map[L"background"] = DPL::MakeDelegate(this, &WidgetParser::OnBackgroundElement);
2181     m_map[L"privilege"] = DPL::MakeDelegate(this, &WidgetParser::OnPrivilegeElement);
2182     m_map[L"app-control"] = DPL::MakeDelegate(this,
2183             &WidgetParser::OnAppControlElement);
2184     m_map[L"category"] = DPL::MakeDelegate(this,
2185             &WidgetParser::OnCategoryElement);
2186     m_map[L"livebox"] = DPL::MakeDelegate(this, &WidgetParser::OnLiveboxElement);
2187
2188 }
2189
2190 ElementParserPtr WidgetParser::OnNameElement()
2191 {
2192     return ElementParserPtr(new NameParser(m_textDirection, m_data));
2193 }
2194
2195 ElementParserPtr WidgetParser::OnAccessElement()
2196 {
2197     return ElementParserPtr(new AccessParser(m_data));
2198 }
2199
2200 ElementParserPtr WidgetParser::OnDescriptionElement()
2201 {
2202     return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2203 }
2204
2205 ElementParserPtr WidgetParser::OnAuthorElement()
2206 {
2207     return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2208 }
2209
2210 ElementParserPtr WidgetParser::OnLicenseElement()
2211 {
2212     return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2213 }
2214
2215 ElementParserPtr WidgetParser::OnIconElement()
2216 {
2217     return ElementParserPtr(new IconParser(m_data));
2218 }
2219
2220 ElementParserPtr WidgetParser::OnContentElement()
2221 {
2222     return ElementParserPtr(new ContentParser(m_data));
2223 }
2224
2225 ElementParserPtr WidgetParser::OnFeatureElement()
2226 {
2227     return ElementParserPtr(new FeatureParser(m_data));
2228 }
2229
2230 ElementParserPtr WidgetParser::OnPreferenceElement()
2231 {
2232     return ElementParserPtr(new PreferenceParser(m_data));
2233 }
2234
2235 ElementParserPtr WidgetParser::OnLinkElement()
2236 {
2237     return ElementParserPtr(new LinkParser(m_data));
2238 }
2239
2240 ElementParserPtr WidgetParser::OnSettingElement()
2241 {
2242     return ElementParserPtr(new SettingParser(m_data));
2243 }
2244
2245 ElementParserPtr WidgetParser::OnApplicationElement()
2246 {
2247     return ElementParserPtr(new ApplicationParser(m_data));
2248 }
2249
2250 ElementParserPtr WidgetParser::OnSplashElement()
2251 {
2252     return ElementParserPtr(new SplashParser(m_data));
2253 }
2254
2255 ElementParserPtr WidgetParser::OnBackgroundElement()
2256 {
2257     return ElementParserPtr(new BackgroundParser(m_data));
2258 }
2259
2260 ElementParserPtr WidgetParser::OnPrivilegeElement()
2261 {
2262     return ElementParserPtr(new PrivilegeParser(m_data));
2263 }
2264
2265 ElementParserPtr WidgetParser::OnAppServiceElement()
2266 {
2267     return ElementParserPtr(new AppServiceParser(m_data));
2268 }
2269
2270 ElementParserPtr WidgetParser::OnAppControlElement()
2271 {
2272     return ElementParserPtr(new AppControlParser(m_data));
2273 }
2274
2275 ElementParserPtr WidgetParser::OnCategoryElement()
2276 {
2277     return ElementParserPtr(new CategoryParser(m_data));
2278 }
2279
2280 ElementParserPtr WidgetParser::OnLiveboxElement()
2281 {
2282     return ElementParserPtr(new LiveboxParser(m_data));
2283 }
2284
2285 void WidgetParser::Accept(const Element& element)
2286 {
2287     if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2288         element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2289     {
2290         ThrowMsg(Exception::ParseError,
2291                  "Wrong xml namespace for widget element");
2292     }
2293 }
2294
2295 void WidgetParser::Accept(const Text& /*text*/)
2296 {
2297     ThrowMsg(Exception::ParseError, "widged element must be empty");
2298 }
2299
2300 void WidgetParser::Accept(const XmlAttribute& attribute)
2301 {
2302     if (attribute.name == L"id") {
2303         LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2304         //If may important tests starts to fail this test we will have
2305         //to consider commenting this test out again.
2306         if (iri.Validate()) {
2307             m_data.widget_id = attribute.value;
2308             NormalizeString(m_data.widget_id);
2309         } else {
2310             LogWarning("Widget id validation failed: " << attribute.value);
2311         }
2312     } else if (attribute.name == L"version") {
2313         m_version = attribute.value;
2314         NormalizeString(m_version);
2315     } else if (attribute.name == L"min-version") {
2316         LogInfo("min-version attribute was found. Value: " << attribute.value);
2317         m_minVersion = attribute.value;
2318         NormalizeString(m_minVersion);
2319         m_data.minVersionRequired = m_minVersion;
2320     } else if (attribute.name == L"height") {
2321         DPL::OptionalString value = attribute.value;
2322         NormalizeString(value);
2323         std::string v = DPL::ToUTF8String(*value);
2324
2325         if (!v.empty()) {
2326             unsigned char c = v.c_str()[0];
2327             if (c >= '0' && c <= '9') {
2328                 int val = 0;
2329                 for (size_t i = 0; i < v.size(); ++i) {
2330                     c = v.c_str()[i];
2331                     if (c >= '0' && c <= '9') {
2332                         val *= 10;
2333                         val += (c - '0');
2334                     } else {
2335                         break;
2336                     }
2337                 }
2338                 m_data.height = val;
2339             }
2340         }
2341     } else if (attribute.name == L"width") {
2342         DPL::OptionalString value = attribute.value;
2343         NormalizeString(value);
2344         std::string v = DPL::ToUTF8String(*value);
2345
2346         if (!v.empty()) {
2347             unsigned char c = v.c_str()[0];
2348             if (c >= '0' && c <= '9') {
2349                 int val = 0;
2350                 for (size_t i = 0; i < v.size(); ++i) {
2351                     c = v.c_str()[i];
2352                     if (c >= '0' && c <= '9') {
2353                         val *= 10;
2354                         val += (c - '0');
2355                     } else {
2356                         break;
2357                     }
2358                 }
2359                 m_data.width = val;
2360             }
2361         }
2362     } else if (attribute.name == L"viewmodes") {
2363         DPL::Tokenize(attribute.value,
2364                       L" ",
2365                       std::inserter(m_windowModes,
2366                                     m_windowModes.end()),
2367                       true);
2368     } else if (attribute.name == L"dir") {
2369         m_textDirection = Unicode::ParseDirAttribute(attribute);
2370     } else if (L"defaultlocale" == attribute.name) {
2371         if (!m_defaultlocale) {
2372             m_defaultlocale = attribute.value;
2373             NormalizeString(m_defaultlocale);
2374             if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag(
2375                     DPL::ToUTF8String(*m_defaultlocale))) {
2376                 LogWarning("Language tag: " <<
2377                            m_defaultlocale << " is not valid");
2378                 m_defaultlocale = DPL::OptionalString::Null;
2379             }
2380             else
2381                 LogDebug("Default Locale Found " << m_defaultlocale);
2382         } else {
2383             LogWarning("Ignoring subsequent default locale");
2384         }
2385
2386     //Any other value consider as a namespace definition
2387     } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2388         LogInfo("Namespace domain: " << attribute.name);
2389         LogInfo("Namespace value: " << attribute.value);
2390         m_nameSpaces[attribute.name] = attribute.value;
2391     } else {
2392         LogError("Unknown attirbute: namespace=" << attribute.ns <<
2393                 ", name=" << attribute.name <<
2394                 ", value=" << attribute.value);
2395     }
2396 }
2397
2398 void WidgetParser::Verify()
2399 {
2400     FOREACH(mode, m_windowModes) {
2401         if (L"windowed" == *mode || L"floating" == *mode ||
2402             L"fullscreen" == *mode || L"maximized" == *mode ||
2403             L"minimized" == *mode) {
2404             m_data.windowModes.insert(*mode);
2405         }
2406     }
2407     if (!m_version.IsNull()) {
2408         Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2409         m_data.version = m_version;
2410     }
2411     m_data.defaultlocale = m_defaultlocale;
2412     FOREACH(ns, m_nameSpaces) {
2413         m_data.nameSpaces.insert(ns->second);
2414     }
2415 }
2416