2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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
22 * @file widget_parser.cpp
23 * @author Lukasz Wrzosek (l.wrzosek@samsung.com)
28 #include <widget_parser.h>
29 #include "ignoring_parser.h"
30 #include "deny_all_parser.h"
31 #include <dpl/wrt-dao-ro/config_parser_data.h>
32 #include "libiriwrapper.h"
33 #include "wrt-commons/i18n-dao-ro/i18n_dao_read_only.h"
34 #include <dpl/utils/warp_iri.h>
35 #include <dpl/utils/mime_type_utils.h>
36 #include <language_subtag_rst_tree.h>
48 #include <boost/optional.hpp>
50 #include <dpl/log/log.h>
51 #include <dpl/foreach.h>
52 #include <dpl/platform.h>
53 #include <dpl/utils/warp_iri.h>
54 #include <dpl/utils/mime_type_utils.h>
55 #include <dpl/wrt-dao-ro/config_parser_data.h>
59 #include <deny_all_parser.h>
60 #include <ignoring_parser.h>
61 #include <dpl/log/secure_log.h>
62 #include <language_subtag_rst_tree.h>
63 #include <libiriwrapper.h>
64 #include <uuid/uuid.h>
66 using namespace WrtDB;
68 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
70 const unsigned int MAX_ATTR_ELEMENT_LENGTH = 2048;
71 const unsigned int MAX_NAME_KEY_LENGTH = 80;
72 const unsigned int MAX_NAME_KEY_VALUE_LENGTH = 8192;
73 } // namespace anonymous
74 #endif // ELEMENT_ATTR_MAX_LENGTH
77 const unsigned int MAX_APPLICATION_ID_LENGTH = 63;
81 static const DPL::String UTF_LRE = L"\x0202a";
82 static const DPL::String UTF_LRO = L"\x0202d";
83 static const DPL::String UTF_RLE = L"\x0202b";
84 static const DPL::String UTF_RLO = L"\x0202e";
85 static const DPL::String UTF_PDF = L"\x0202c";
87 Direction ParseDirAttribute(const XmlAttribute& attribute)
89 Assert(L"dir" == attribute.name);
90 if (L"ltr" == attribute.value) {
92 } else if (L"rtl" == attribute.value) {
94 } else if (L"lro" == attribute.value) {
96 } else if (L"rlo" == attribute.value) {
99 _W("dir attribute has wrong value: %ls ", attribute.value.c_str());
104 void UpdateTextWithDirectionMark(Direction direction,
110 *text = UTF_RLO + *text + UTF_PDF;
113 *text = UTF_RLE + *text + UTF_PDF;
116 *text = UTF_LRE + *text + UTF_PDF;
119 *text = UTF_LRO + *text + UTF_PDF;
128 } // namespace Unicode
131 class InnerElementsParser : public ElementParser
134 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
135 const DPL::String& /*name*/)
137 return std::bind(&InnerElementsParser::Other, this);
140 virtual void Accept(const Element& /*element*/)
143 virtual void Accept(const Text& text)
148 m_text->value += text.value;
152 virtual void Accept(const XmlAttribute& attribute)
154 if (attribute.name == L"dir") {
155 m_textDirection = Unicode::ParseDirAttribute(attribute);
159 virtual void Verify()
162 Unicode::UpdateTextWithDirectionMark(m_textDirection,
164 m_parentParser->Accept(*m_text);
168 InnerElementsParser(ElementParserPtr parent) :
169 m_parentParser(parent),
170 m_textDirection(Unicode::EMPTY)
173 ElementParserPtr Other()
175 return ElementParserPtr(new InnerElementsParser(
176 std::static_pointer_cast<ElementParser>(
177 shared_from_this())));
181 boost::optional<Text> m_text;
182 ElementParserPtr m_parentParser;
183 Unicode::Direction m_textDirection;
186 class NameParser : public ElementParser
189 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
190 const DPL::String& /*name*/)
192 return std::bind(&NameParser::Other, this);
195 virtual void Accept(const Element& element)
197 m_lang = element.lang;
201 virtual void Accept(const Text& text)
206 *m_name += text.value;
210 virtual void Accept(const XmlAttribute& attribute)
212 if (attribute.name == L"short") {
214 m_shortName = attribute.value;
216 } else if (attribute.name == L"dir") {
217 m_textDirection = Unicode::ParseDirAttribute(attribute);
221 virtual void Verify()
223 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
226 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
227 NormalizeString(m_name, MAX_ATTR_ELEMENT_LENGTH, true);
229 NormalizeString(m_name);
231 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
235 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
236 NormalizeString(m_shortName, MAX_ATTR_ELEMENT_LENGTH, true);
238 NormalizeString(m_shortName);
240 Unicode::UpdateTextWithDirectionMark(m_textDirection,
242 data.shortName = m_shortName;
247 NameParser(Unicode::Direction direction,
248 ConfigParserData& data) :
250 m_textDirection(direction)
253 ElementParserPtr Other()
255 return ElementParserPtr(new InnerElementsParser(
256 std::static_pointer_cast<ElementParser>(
257 shared_from_this())));
261 ConfigParserData& m_data;
262 DPL::OptionalString m_name;
263 DPL::OptionalString m_shortName;
264 DPL::OptionalString m_dir;
266 Unicode::Direction m_textDirection;
269 class AccessParser : public ElementParser
278 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
279 const DPL::String& /*name*/)
281 return std::bind(&AccessParser::Other, this);
284 virtual void Accept(const Element& element)
286 // for tizen web apps WARP should be used
287 if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
288 element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
290 m_standardType = STANDARD_TYPE_WARP;
294 virtual void Accept(const Text& /*text*/)
297 void AcceptWac(const XmlAttribute& attribute)
299 if (attribute.name == L"origin") {
300 m_strIRIOrigin = attribute.value;
301 } else if (attribute.name == L"subdomains") {
302 DPL::String normalizedValue = attribute.value;
303 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
304 NormalizeString(normalizedValue, MAX_ATTR_ELEMENT_LENGTH, true);
306 NormalizeString(normalizedValue);
308 if (normalizedValue == L"true") {
309 m_bSubDomainAccess = true;
311 m_bSubDomainAccess = false;
316 virtual void Accept(const XmlAttribute& attribute)
318 switch (m_standardType) {
319 case STANDARD_TYPE_WARP:
320 AcceptWac(attribute);
323 _E("Error in Access tag - unknown standard.");
330 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
331 NormalizeString(m_strIRIOrigin, MAX_ATTR_ELEMENT_LENGTH, true);
333 NormalizeString(m_strIRIOrigin);
337 iri.set(m_strIRIOrigin, false);
339 if (!iri.isAccessDefinition()) {
340 _W("Access list element: %ls is not acceptable by WARP standard and will be ignored!",
341 m_strIRIOrigin.c_str());
345 if(m_strIRIOrigin == L"*") //wildcard match means yes for subdomains
347 m_bSubDomainAccess = true;
350 ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
352 //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
353 m_data.accessInfoSet.insert(accessInfo);
356 virtual void Verify()
358 switch (m_standardType) {
359 case STANDARD_TYPE_WARP:
363 _E("Error in Access tag - unknown standard.");
368 AccessParser(ConfigParserData& data) :
370 m_bSubDomainAccess(false),
371 m_standardType(STANDARD_TYPE_NONE),
376 ElementParserPtr Other()
378 return ElementParserPtr(new InnerElementsParser(
379 ElementParserPtr(shared_from_this())));
383 DPL::String m_strIRIOrigin;
384 bool m_bSubDomainAccess;
385 StandardType m_standardType;
387 ConfigParserData& m_data;
390 class DescriptionParser : public ElementParser
393 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
394 const DPL::String& /*name*/)
396 return std::bind(&DescriptionParser::Other, this);
399 virtual void Accept(const Element& element)
401 m_lang = element.lang;
405 ElementParserPtr Other()
407 return ElementParserPtr(new InnerElementsParser(
408 std::static_pointer_cast<ElementParser>(
409 shared_from_this())));
412 virtual void Accept(const Text& text)
414 if (!m_description) {
415 m_description = text.value;
417 *m_description += text.value;
421 virtual void Accept(const XmlAttribute& attribute)
423 if (attribute.name == L"dir") {
424 m_textDirection = Unicode::ParseDirAttribute(attribute);
428 virtual void Verify()
430 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
431 if (!data.description) {
432 if (!!m_description) {
433 Unicode::UpdateTextWithDirectionMark(m_textDirection,
436 data.description = m_description;
440 DescriptionParser(Unicode::Direction direction,
441 ConfigParserData& data) :
445 m_textDirection(direction)
449 ConfigParserData& m_data;
451 DPL::OptionalString m_description;
452 Unicode::Direction m_textDirection;
455 class AuthorParser : public ElementParser
458 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
459 const DPL::String& /*name*/)
461 return std::bind(&AuthorParser::Other, this);
464 AuthorParser(Unicode::Direction direction,
465 ConfigParserData& data) :
467 m_textDirection(direction)
470 virtual void Accept(const Element& /*element*/)
475 virtual void Accept(const Text& text)
477 *(m_authorName) += text.value;
480 virtual void Accept(const XmlAttribute& attribute)
482 if (attribute.name == L"href") {
483 //Validate href IRI and ignore it if invalid
484 //See also test: ta-argMozRiC-an
485 LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
486 if (iri.Validate()) {
487 m_authorHref = attribute.value;
489 } else if (attribute.name == L"email") {
490 m_authorEmail = attribute.value;
491 } else if (attribute.name == L"dir") {
492 m_textDirection = Unicode::ParseDirAttribute(attribute);
496 virtual void Verify()
498 if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) {
499 if (!!m_authorName) {
500 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
501 NormalizeString(m_authorName, MAX_ATTR_ELEMENT_LENGTH, true);
503 NormalizeString(m_authorName);
505 Unicode::UpdateTextWithDirectionMark(m_textDirection,
507 m_data.authorName = m_authorName;
509 if (!!m_authorHref) {
510 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
511 NormalizeString(m_authorHref, MAX_ATTR_ELEMENT_LENGTH, true);
513 NormalizeString(m_authorHref);
515 m_data.authorHref = m_authorHref;
517 if (!!m_authorEmail) {
518 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
519 NormalizeString(m_authorEmail, MAX_ATTR_ELEMENT_LENGTH, true);
521 NormalizeString(m_authorEmail);
523 m_data.authorEmail = m_authorEmail;
528 ElementParserPtr Other()
530 return ElementParserPtr(new InnerElementsParser(
531 std::static_pointer_cast<ElementParser>(
532 shared_from_this())));
536 ConfigParserData& m_data;
537 DPL::OptionalString m_authorEmail;
538 DPL::OptionalString m_authorHref;
539 DPL::OptionalString m_authorName;
540 Unicode::Direction m_textDirection;
543 class LicenseParser : public ElementParser
546 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
547 const DPL::String& /*name*/)
549 return std::bind(&LicenseParser::Other, this);
552 LicenseParser(Unicode::Direction direction,
553 ConfigParserData& data) :
556 m_textDirection(direction)
559 virtual void Accept(const Element& element)
562 m_lang = element.lang;
568 virtual void Accept(const Text& text)
571 *m_license += text.value;
575 virtual void Accept(const XmlAttribute& attribute)
578 if (attribute.name == L"href" && !m_licenseHref) {
579 m_licenseHref = attribute.value;
580 } else if (attribute.name == L"file" && !m_licenseFile) {
581 m_licenseFile = attribute.value;
582 } else if (attribute.name == L"dir") {
583 m_textDirection = Unicode::ParseDirAttribute(attribute);
588 virtual void Verify()
590 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
593 Unicode::UpdateTextWithDirectionMark(m_textDirection,
596 data.license = m_license;
597 data.licenseHref = m_licenseHref;
598 data.licenseFile = m_licenseFile;
602 ElementParserPtr Other()
604 return ElementParserPtr(new InnerElementsParser(
605 ElementParserPtr(shared_from_this())));
609 ConfigParserData& m_data;
613 DPL::OptionalString m_license;
614 DPL::OptionalString m_licenseFile;
615 DPL::OptionalString m_licenseHref;
616 Unicode::Direction m_textDirection;
619 class IconParser : public ElementParser
621 DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
624 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
625 const DPL::String& /*name*/)
627 return &IgnoringParser::Create; //ignore unknown according to w3c
630 IconParser(ConfigParserData& data) : ElementParser(),
631 m_data(data), m_isSmall(false)
634 IconParser(ConfigParserData& data, bool isSmall) : ElementParser(),
635 m_data(data), m_isSmall(isSmall)
638 virtual void Accept(const Element& /*element*/)
641 virtual void Accept(const XmlAttribute& attribute)
643 if (attribute.name == L"src") {
644 if (attribute.value.size() > 0) {
645 m_src = attribute.value;
647 } else if (attribute.name == L"width") {
648 m_width = ParseSizeAttributeValue(attribute.value);
649 } else if (attribute.name == L"height") {
650 m_height = ParseSizeAttributeValue(attribute.value);
654 virtual void Accept(const Text& /*text*/)
656 ThrowMsg(Exception::ParseError, "Icon element must be empty");
659 virtual void Verify()
662 _W("src attribute of icon element is mandatory - ignoring");
668 ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
669 icon.width = m_width;
670 icon.height = m_height;
671 icon.isSmall = m_isSmall;
673 ConfigParserData::IconsList::iterator it = std::find(
674 m_data.iconsList.begin(), m_data.iconsList.end(), icon);
675 if (it == m_data.iconsList.end()) {
676 m_data.iconsList.push_front(icon);
681 _W("src attribute is invalid: %ls", (*m_src).c_str());
686 ConfigParserData& m_data;
687 DPL::OptionalString m_src;
688 DPL::OptionalInt m_width;
689 DPL::OptionalInt m_height;
692 static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
694 DPL::OptionalString normalizedValue = value;
695 if (!(*normalizedValue).empty()) {
696 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
697 NormalizeString(normalizedValue, MAX_ATTR_ELEMENT_LENGTH, true);
699 NormalizeString(normalizedValue);
704 strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
706 std::string(reterr) == DPL::ToUTF8String(value) ||
709 return DPL::OptionalInt();
714 return DPL::OptionalInt();
718 * @brief delocalizePath removes locales folder from relative path if
720 * @param source source string
722 * @throw BadSrcError if string is bad value of src attribute
724 * @return corrected string
726 static DPL::String delocalizeSrcPath(const DPL::String & source)
728 static const DPL::String localeFolder(L"locales/");
729 static const int index = localeFolder.size();
731 DPL::String result = source;
733 if (source.substr(0, index) == localeFolder) {
734 size_t pos = result.find_first_of('/', index);
735 if (pos != std::string::npos && pos + 1 < source.size()) {
736 result = result.substr(pos + 1, source.size());
745 class ContentParser : public ElementParser
748 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
749 const DPL::String& /*name*/)
751 return &IgnoringParser::Create; //ignore unknown according to w3c
754 ContentParser(ConfigParserData& data) :
759 virtual void Accept(const Element& element)
761 m_namespace = element.ns;
764 virtual void Accept(const Text& /*text*/)
767 virtual void Accept(const XmlAttribute& attribute)
769 DPL::String value = attribute.value;
771 if (attribute.name == L"src") {
773 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
774 NormalizeString(m_src, MAX_ATTR_ELEMENT_LENGTH, true);
776 NormalizeString(m_src);
778 } else if (attribute.name == L"type") {
780 MimeTypeUtils::MimeAttributes mimeAttributes =
781 MimeTypeUtils::getMimeAttributes(value);
782 if ((mimeAttributes.count(L"charset") > 0) && !m_encoding)
784 m_encoding = mimeAttributes[L"charset"];
786 } else if (attribute.name == L"encoding") {
787 if (!value.empty()) {
793 virtual void Verify()
795 if(!!m_data.startFileEncountered)
797 if(m_data.startFileNamespace == m_namespace
798 || m_namespace != ConfigurationNamespace::TizenWebAppNamespaceName)
802 //else continue -> if previous item was not in tizen namespace
805 m_data.startFileEncountered = true;
806 m_data.startFileNamespace = m_namespace;
808 if (m_namespace == ConfigurationNamespace::TizenWebAppNamespaceName &&
809 (!m_src || m_src->empty())) {
810 ThrowMsg(Exception::ParseError, "content element must have correct src element");
814 m_data.startFile = m_src;
816 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
817 NormalizeString(m_type, MAX_ATTR_ELEMENT_LENGTH, true);
819 NormalizeString(m_type);
821 m_data.startFileContentType = m_type;
824 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
825 NormalizeString(m_encoding, MAX_ATTR_ELEMENT_LENGTH, true);
827 NormalizeString(m_encoding);
829 m_data.startFileEncoding = m_encoding;
831 m_data.startFileEncoding = L"UTF-8";
837 DPL::OptionalString m_src;
838 DPL::OptionalString m_type;
839 DPL::OptionalString m_encoding;
840 ConfigParserData& m_data;
841 DPL::String m_namespace;
844 class PreferenceParser : public ElementParser
847 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
848 const DPL::String& /*name*/)
850 return &IgnoringParser::Create; //ignore unknown according to w3c
853 virtual void Accept(const XmlAttribute& attribute)
855 if (attribute.name == L"name") {
856 m_name = attribute.value;
857 } else if (attribute.name == L"value") {
858 m_value = attribute.value;
859 } else if (attribute.name == L"readonly") {
860 if (attribute.value == L"true") {
868 virtual void Accept(const Element& /*element*/)
871 virtual void Accept(const Text& /*text*/)
873 ThrowMsg(Exception::ParseError, "param element must be empty");
876 virtual void Verify()
879 _W("preference element must have name attribute");
882 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
883 NormalizeString(m_name, MAX_NAME_KEY_LENGTH, true);
884 NormalizeString(m_value, MAX_NAME_KEY_VALUE_LENGTH, true);
886 NormalizeString(m_name);
887 NormalizeString(m_value);
889 ConfigParserData::Preference preference(*m_name, m_required);
890 preference.value = m_value;
891 if (m_data.preferencesList.find(preference) ==
892 m_data.preferencesList.end())
894 m_data.preferencesList.insert(preference);
898 PreferenceParser(ConfigParserData& data) :
905 DPL::OptionalString m_name;
906 DPL::OptionalString m_value;
908 ConfigParserData& m_data;
911 class SettingParser : public ElementParser
914 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
915 const DPL::String& /*name*/)
917 return &IgnoringParser::Create; //ignore unknown according to w3c
920 virtual void Accept(const Text& /*text*/)
923 virtual void Accept(const Element& /*element*/)
926 virtual void Accept(const XmlAttribute& attribute)
928 m_setting.m_name = attribute.name;
929 m_setting.m_value = attribute.value;
930 m_data.settingsList.insert(m_setting);
933 virtual void Verify()
935 if(m_data.serviceAppInfoList.size() > 0) {
936 FOREACH(it, m_data.settingsList) {
937 if (it->m_name == L"encryption" && it->m_value == L"enable") {
938 ThrowMsg(Exception::ParseError, "Service application does not support application encryption");
944 SettingParser(ConfigParserData& data) :
951 ConfigParserData& m_data;
952 ConfigParserData::Setting m_setting;
955 class AppControlParser : public ElementParser
958 struct SourceParser : public ElementParser
961 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
962 const DPL::String& /*name*/)
964 return &IgnoringParser::Create; //ignore unknown according to w3c
967 virtual void Accept(const Text& /*text*/)
970 virtual void Accept(const Element& /*element*/)
973 virtual void Accept(const XmlAttribute& attribute)
975 if (attribute.name == L"name") {
976 if (attribute.value.size() > 0) {
977 m_value = attribute.value;
979 } else if (attribute.name == L"reload") {
980 m_reload = attribute.value;
984 virtual void Verify()
986 if (!m_value || *m_value == L"") {
989 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
990 NormalizeString(m_value, MAX_ATTR_ELEMENT_LENGTH, true);
992 NormalizeString(m_value);
994 m_appControl.m_src = *m_value;
997 if (*m_reload == L"enable") {
998 m_appControl.m_reload = L"true";
999 } else if (*m_reload == L"disable") {
1000 m_appControl.m_reload = L"false";
1002 ThrowMsg(Exception::ParseError, "Wrong reload value. enable or disable");
1007 SourceParser(ConfigParserData::AppControlInfo& appControl, ConfigParserData& data) :
1009 m_properNamespace(false),
1010 m_appControl(appControl),
1015 bool m_properNamespace;
1016 DPL::OptionalString m_reload;
1017 DPL::OptionalString m_value;
1018 ConfigParserData::AppControlInfo& m_appControl;
1019 ConfigParserData& m_data;
1022 struct OperationParser : public ElementParser
1025 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1026 const DPL::String& /*name*/)
1028 return &IgnoringParser::Create; //ignore unknown according to w3c
1031 virtual void Accept(const Text& /*text*/)
1034 virtual void Accept(const Element& /*element*/)
1037 virtual void Accept(const XmlAttribute& attribute)
1039 if (attribute.name == L"name") {
1040 if (attribute.value.size() > 0) {
1041 m_value = attribute.value;
1046 virtual void Verify()
1048 if (!m_value || *m_value == L"") {
1051 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
1052 NormalizeString(m_value, MAX_ATTR_ELEMENT_LENGTH, true);
1054 NormalizeString(m_value);
1056 m_appControl.m_operation = *m_value;
1059 OperationParser(ConfigParserData::AppControlInfo& data) :
1061 m_properNamespace(false),
1066 bool m_properNamespace;
1067 DPL::OptionalString m_value;
1068 ConfigParserData::AppControlInfo& m_appControl;
1071 struct UriParser : public ElementParser
1074 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1075 const DPL::String& /*name*/)
1077 return &IgnoringParser::Create; //ignore unknown according to w3c
1080 virtual void Accept(const Text& /*text*/)
1083 virtual void Accept(const Element& /*element*/)
1086 virtual void Accept(const XmlAttribute& attribute)
1088 if (attribute.name == L"name") {
1089 if (attribute.value.size() > 0) {
1090 m_value = attribute.value;
1095 virtual void Verify()
1098 DPL::String ignoreUri(L"file");
1100 if (!!m_value && *m_value == ignoreUri)
1102 _D("exception : '%ls' scheme will be ignored.", (*m_value).c_str());
1103 m_value = DPL::OptionalString();
1106 if (!m_value || *m_value == L"") {
1109 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
1110 NormalizeString(m_value, MAX_ATTR_ELEMENT_LENGTH, true);
1112 NormalizeString(m_value);
1114 DPL::String wildString(L"*/*");
1115 if ((m_appControl.m_uriList.find(wildString) == m_appControl.m_uriList.end())
1116 && (m_appControl.m_uriList.find(*m_value) == m_appControl.m_uriList.end()))
1118 m_appControl.m_uriList.insert(*m_value);
1120 _D("Ignoring uri with name %ls", (*m_value).c_str());
1124 UriParser(ConfigParserData::AppControlInfo& data) :
1126 m_properNamespace(false),
1131 bool m_properNamespace;
1132 DPL::OptionalString m_value;
1133 ConfigParserData::AppControlInfo& m_appControl;
1136 struct MimeParser : public ElementParser
1139 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1140 const DPL::String& /*name*/)
1142 return &IgnoringParser::Create; //ignore unknown according to w3c
1145 virtual void Accept(const Text& /*text*/)
1148 virtual void Accept(const Element& /*element*/)
1151 virtual void Accept(const XmlAttribute& attribute)
1153 if (attribute.name == L"name") {
1154 if (attribute.value.size() > 0) {
1155 m_value = attribute.value;
1160 virtual void Verify()
1162 if (!m_value || *m_value == L"") {
1165 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
1166 NormalizeString(m_value, MAX_ATTR_ELEMENT_LENGTH, true);
1168 NormalizeString(m_value);
1170 DPL::String wildString(L"*/*");
1171 if ((m_appControl.m_mimeList.find(wildString) ==
1172 m_appControl.m_mimeList.end())
1173 && (m_appControl.m_mimeList.find(*m_value) ==
1174 m_appControl.m_mimeList.end()))
1176 m_appControl.m_mimeList.insert(*m_value);
1178 _D("Ignoring mime with name %ls", (*m_value).c_str());
1182 MimeParser(ConfigParserData::AppControlInfo& data) :
1184 m_properNamespace(false),
1189 bool m_properNamespace;
1190 DPL::OptionalString m_value;
1191 ConfigParserData::AppControlInfo& m_appControl;
1194 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1195 const DPL::String& name)
1197 if (name == L"src") {
1198 return std::bind(&AppControlParser::OnSourceElement, this);
1199 } else if (name == L"operation") {
1200 return std::bind(&AppControlParser::OnOperationElement, this);
1201 } else if (name == L"uri") {
1202 return std::bind(&AppControlParser::OnUriElement, this);
1203 } else if (name == L"mime") {
1204 return std::bind(&AppControlParser::OnMimeElement, this);
1206 return &IgnoringParser::Create; //ignore unknown according to w3c
1210 virtual void Accept(const XmlAttribute& /*attribute*/)
1213 virtual void Accept(const Element& element)
1215 _W("namespace for app service = %ls", element.ns.c_str());
1216 if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1217 ThrowMsg(Exception::ParseError,
1218 "Wrong xml namespace for widget element");
1222 virtual void Accept(const Text& /*text*/)
1224 ThrowMsg(Exception::ParseError, "param element must be empty");
1227 virtual void Verify()
1229 if (m_appControl.m_src == L"") {
1230 ThrowMsg(Exception::ParseError, "service element must have src element");
1233 if (m_appControl.m_operation == L"") {
1234 ThrowMsg(Exception::ParseError, "service element must have operation element");
1237 auto res = std::find(m_data.appControlList.begin(), m_data.appControlList.end(), m_appControl);
1238 if(res != m_data.appControlList.end()) {
1239 ThrowMsg(Exception::ParseError, "service element must be unique");
1242 #ifdef NFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY
1243 // XXX This feature should be retained to Tizen 2.2 only.
1244 // NFC exception handling which was requested from Tizen Device API team.
1246 const DPL::String exceptionNfcOperation =
1247 L"http://tizen.org/appcontrol/operation/nfc/transaction";
1248 const DPL::String exceptionNfcUri = L"nfc://secure/aid/";
1249 const DPL::String divertingNfcUri1 = L"nfc://secure/SIM1/aid/";
1250 const DPL::String divertingNfcUri2 = L"nfc://secure/eSE/aid/";
1252 if (m_appControl.m_operation == exceptionNfcOperation
1253 && m_appControl.m_mimeList.empty()
1254 && m_appControl.m_uriList.size() == 1
1255 && (m_appControl.m_uriList.begin())->compare(0, exceptionNfcUri.length(), exceptionNfcUri) == 0)
1257 DPL::String originalUri = *m_appControl.m_uriList.begin();
1258 DPL::String newUri = originalUri;
1260 newUri.replace(0, exceptionNfcUri.length(), divertingNfcUri1);
1261 m_appControl.m_uriList.erase(m_appControl.m_uriList.begin());
1262 m_appControl.m_uriList.insert(newUri);
1263 m_data.appControlList.push_back(m_appControl);
1264 _D("NFC exception : %ls -> %ls", originalUri.c_str(), newUri.c_str());
1266 newUri = originalUri;
1267 newUri.replace(0, exceptionNfcUri.length(), divertingNfcUri2);
1268 m_appControl.m_uriList.erase(m_appControl.m_uriList.begin());
1269 m_appControl.m_uriList.insert(newUri);
1270 m_data.appControlList.push_back(m_appControl);
1271 _D("NFC exception : %ls -> %ls", originalUri.c_str(), newUri.c_str());
1275 #endif // NFC_EXCEPTION_HANDLING_FOR_TIZEN_2_2_ONLY
1277 m_data.appControlList.push_back(m_appControl);
1280 ElementParserPtr OnSourceElement()
1282 return ElementParserPtr(new SourceParser(m_appControl, m_data));
1285 ElementParserPtr OnOperationElement()
1287 return ElementParserPtr(new OperationParser(m_appControl));
1290 ElementParserPtr OnUriElement()
1292 return ElementParserPtr(new UriParser(m_appControl));
1295 ElementParserPtr OnMimeElement()
1297 return ElementParserPtr(new MimeParser(m_appControl));
1300 AppControlParser(ConfigParserData& data) :
1307 ConfigParserData& m_data;
1308 ConfigParserData::AppControlInfo m_appControl;
1311 class ApplicationParser : public ElementParser
1314 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1315 const DPL::String& /*name*/)
1317 return &IgnoringParser::Create; //ignore unknown according to w3c
1320 virtual void Accept(const Text& /*text*/)
1322 if (m_properNamespace) {
1323 ThrowMsg(Exception::ParseError, "application element must be empty");
1327 virtual void Accept(const Element& element)
1330 ConfigurationNamespace::TizenWebAppNamespaceName)
1332 m_properNamespace = true;
1336 virtual void Accept(const XmlAttribute& attribute)
1338 if (m_properNamespace) {
1339 if (attribute.name == L"id") {
1340 if (attribute.value.length() > MAX_APPLICATION_ID_LENGTH) {
1341 ThrowMsg(Exception::ParseError,
1342 "length of application id has crossed the allowed limit");
1344 m_id = attribute.value;
1345 NormalizeAndTrimSpaceString(m_id);
1347 } else if (attribute.name == L"package") {
1348 m_package = attribute.value;
1349 } else if (attribute.name == L"required_version") {
1350 m_version = attribute.value;
1351 } else if (attribute.name == L"launch_mode") {
1352 m_launchMode = attribute.value;
1353 #ifdef AMBIENT_ENABLED
1354 } else if (attribute.name == L"ambient_support") {
1355 m_ambient = attribute.value;
1358 ThrowMsg(Exception::ParseError,
1359 "unknown attribute '" +
1360 DPL::ToUTF8String(attribute.name) +
1361 "' in application element");
1366 virtual void Verify()
1368 if (m_data.didFoundTizenApplicationElement) {
1369 ThrowMsg(Exception::ParseError, "tizen:application element must occur only once");
1371 m_data.didFoundTizenApplicationElement = true;
1373 VerifyIdAndPackage();
1376 if (!!m_launchMode) {
1377 if (*m_launchMode != L"caller" && *m_launchMode != L"group" && *m_launchMode != L"single") {
1378 ThrowMsg(Exception::ParseError, "Wrong launch_mode value. only caller, single and group are acceptable");
1380 m_data.launchMode = m_launchMode;
1383 #ifdef AMBIENT_ENABLED
1385 if (*m_ambient == L"enable") {
1386 m_data.ambient = L"true";
1387 } else if (*m_ambient == L"disable") {
1388 m_data.ambient = L"false";
1390 ThrowMsg(Exception::ParseError, "Wrong ambient_support value. enable or disable");
1396 ApplicationParser(ConfigParserData& data) :
1399 m_id(DPL::OptionalString()),
1400 m_version(DPL::OptionalString()),
1401 m_launchMode(DPL::OptionalString()),
1402 #ifdef AMBIENT_ENABLED
1403 m_ambient(DPL::OptionalString()),
1405 m_properNamespace(false)
1408 static const char* const REGEXP_ID;
1411 void VerifyIdAndPackage()
1415 ThrowMsg(Exception::ParseError,
1416 "application element must have package attribute");
1420 pcrecpp::RE re(REGEXP_PACKAGE);
1421 if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
1423 ThrowMsg(Exception::ParseError,
1424 "invalid format of package attribute");
1429 ThrowMsg(Exception::ParseError,
1430 "application element must have id attribute");
1434 std::string package;
1435 pcrecpp::RE re(REGEXP_ID);
1436 if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
1438 ThrowMsg(Exception::ParseError,
1439 "invalid format of id attribute");
1441 if (package != DPL::ToUTF8String(*m_package))
1443 ThrowMsg(Exception::ParseError,
1444 "invalid package prefix in id attribute");
1448 m_data.tizenAppId = m_id;
1449 m_data.tizenPkgId = m_package;
1452 void VerifyVersion()
1456 ThrowMsg(Exception::ParseError,
1457 "application element must have required_version attribute");
1461 pcrecpp::RE re(REGEXP_VERSION);
1462 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
1463 NormalizeString(m_version, MAX_ATTR_ELEMENT_LENGTH, true);
1465 NormalizeString(m_version);
1467 if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
1469 ThrowMsg(Exception::ParseError,
1470 "invalid format of version attribute");
1474 m_data.tizenMinVersionRequired = m_version;
1477 static const char* const REGEXP_PACKAGE;
1478 static const char* const REGEXP_VERSION;
1480 ConfigParserData& m_data;
1481 DPL::OptionalString m_id;
1482 DPL::OptionalString m_package;
1483 DPL::OptionalString m_version;
1484 DPL::OptionalString m_launchMode;
1485 #ifdef AMBIENT_ENABLED
1486 DPL::OptionalString m_ambient;
1488 bool m_properNamespace;
1491 const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
1492 const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
1493 const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)*";
1495 class SplashParser : public ElementParser
1498 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1499 const DPL::String& /*name*/)
1501 return &IgnoringParser::Create; //ignore unknown according to w3c
1504 virtual void Accept(const XmlAttribute& attribute)
1506 if (m_properNamespace)
1508 if (attribute.name == L"src") {
1509 if (attribute.value.size() > 0) {
1510 m_src = attribute.value;
1516 virtual void Accept(const Element& element)
1519 ConfigurationNamespace::TizenWebAppNamespaceName)
1521 m_properNamespace = true;
1525 virtual void Accept(const Text& /*text*/)
1528 virtual void Verify()
1532 _W("src attribute of splash element is mandatory - ignoring");
1536 m_data.splashImgSrc = m_src;
1539 SplashParser(ConfigParserData& data) :
1542 m_properNamespace(false)
1546 DPL::OptionalString m_src;
1547 ConfigParserData& m_data;
1548 bool m_properNamespace;
1551 class BackgroundParser : public ElementParser
1554 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1555 const DPL::String& /*name*/)
1557 return &IgnoringParser::Create; //ignore unknown according to w3c
1560 virtual void Accept(const XmlAttribute& attribute)
1562 if (attribute.name == L"src") {
1563 if (attribute.value.size() > 0) {
1564 m_src = attribute.value;
1569 virtual void Accept(const Element& /*element*/)
1572 virtual void Accept(const Text& /*text*/)
1575 virtual void Verify()
1578 _W("src attribute of background element is mandatory - ignoring");
1582 m_data.backgroundPage = m_src;
1585 explicit BackgroundParser(ConfigParserData& data) :
1590 DPL::OptionalString m_src;
1591 ConfigParserData& m_data;
1594 class PrivilegeParser : public ElementParser
1597 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1598 const DPL::String& /*name*/)
1600 return &IgnoringParser::Create; //ignore unknown according to w3c
1603 virtual void Accept(const Text& /*text*/)
1606 virtual void Accept(const Element& element)
1609 ConfigurationNamespace::TizenWebAppNamespaceName)
1611 m_properNamespace = true;
1616 virtual void Accept(const XmlAttribute& attribute)
1618 if (m_properNamespace) {
1619 if (attribute.name == L"name") {
1620 m_feature.name = attribute.value;
1621 m_privilege.name = attribute.value;
1626 virtual void Verify()
1628 LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1630 if (m_feature.name != L"") {
1631 if (iri.Validate()) {
1632 if (m_data.featuresList.find(m_feature) ==
1633 m_data.featuresList.end())
1635 m_data.featuresList.insert(m_feature);
1637 _D("Ignoring feature with name %ls", m_feature.name.c_str());
1642 LibIri::Wrapper iriPrivilege(
1643 DPL::ToUTF8String(m_privilege.name).c_str());
1645 if (m_privilege.name != L"") {
1646 if (iriPrivilege.Validate()) {
1647 if (m_data.privilegeList.find(m_privilege) ==
1648 m_data.privilegeList.end())
1650 m_data.privilegeList.insert(m_privilege);
1652 _D("Ignoring privilege with name %ls", m_privilege.name.c_str());
1658 PrivilegeParser(ConfigParserData& data) :
1663 m_properNamespace(false)
1667 ConfigParserData& m_data;
1668 ConfigParserData::Feature m_feature;
1669 ConfigParserData::Privilege m_privilege;
1670 bool m_properNamespace;
1673 class CategoryParser : public ElementParser
1676 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1677 const DPL::String& /*name*/)
1679 return &IgnoringParser::Create; //ignore unknown according to w3c
1682 virtual void Accept(const Element& element)
1685 ConfigurationNamespace::TizenWebAppNamespaceName)
1687 m_properNamespace = true;
1692 virtual void Accept(const XmlAttribute& attribute)
1694 if (m_properNamespace) {
1695 if (attribute.name == L"name") {
1696 if (attribute.value.size() > 0) {
1697 m_name = attribute.value;
1703 virtual void Accept(const Text& /*text*/)
1706 virtual void Verify()
1709 _W("name attribute of category element is mandatory - ignoring");
1713 if (m_data.categoryList.find(*m_name) ==
1714 m_data.categoryList.end())
1716 m_data.categoryList.insert(*m_name);
1720 explicit CategoryParser(ConfigParserData& data) :
1722 m_properNamespace(false)
1726 DPL::OptionalString m_name;
1727 ConfigParserData& m_data;
1728 bool m_properNamespace;
1731 class BackgroundCategoryParser : public ElementParser
1734 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1735 const DPL::String& /*name*/)
1737 return &IgnoringParser::Create; //ignore unknown according to w3c
1740 virtual void Accept(const XmlAttribute& attribute)
1742 if (attribute.name == L"value") {
1743 if (attribute.value.size() > 0) {
1744 m_value = attribute.value;
1749 virtual void Accept(const Element& /*element*/)
1752 virtual void Accept(const Text& /*text*/)
1755 virtual void Verify()
1758 _W("value attribute of background-category element is mandatory - ignoring");
1762 if (m_data.backgroundCategoryList.find(*m_value) ==
1763 m_data.backgroundCategoryList.end())
1765 m_data.backgroundCategoryList.insert(*m_value);
1769 explicit BackgroundCategoryParser(ConfigParserData& data) :
1774 DPL::OptionalString m_value;
1775 ConfigParserData& m_data;
1778 #if USE(WEB_PROVIDER)
1779 class AppWidgetParser : public ElementParser
1783 struct BoxLabelParser : public ElementParser
1785 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1786 const DPL::String& /*name*/)
1788 return &IgnoringParser::Create; //ignore unknown according to w3c
1791 virtual void Accept(const XmlAttribute& attribute)
1793 if (m_properNamespace) {
1794 m_lang = attribute.lang;
1797 virtual void Accept(const Element& element)
1800 ConfigurationNamespace::TizenWebAppNamespaceName)
1802 m_properNamespace = true;
1806 virtual void Accept(const Text& text)
1808 if (m_properNamespace) {
1809 m_label = text.value;
1813 virtual void Verify()
1815 std::pair<DPL::String, DPL::String> boxLabel;
1816 if (m_label.empty()) {
1817 _W("box-label element is empty");
1818 boxLabel.first = DPL::FromUTF8String("");
1819 boxLabel.second = DPL::FromUTF8String("");
1820 m_data.m_label.push_back(boxLabel);
1823 boxLabel.first = m_lang;
1824 boxLabel.second = m_label;
1825 m_data.m_label.push_back(boxLabel);
1829 BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1831 m_properNamespace(false),
1837 DPL::String m_label;
1838 bool m_properNamespace;
1839 ConfigParserData::LiveboxInfo& m_data;
1842 struct BoxIconParser : public ElementParser
1844 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1845 const DPL::String& /*name*/)
1847 return &IgnoringParser::Create; //ignore unknown according to w3c
1850 virtual void Accept(const XmlAttribute& attribute)
1852 if (m_properNamespace) {
1853 if (attribute.name == L"src") {
1854 m_icon = attribute.value;
1859 virtual void Accept(const Element& element)
1862 ConfigurationNamespace::TizenWebAppNamespaceName)
1864 m_properNamespace = true;
1868 virtual void Accept(const Text& /*text*/)
1871 virtual void Verify()
1873 if (m_icon.empty()) {
1874 ThrowMsg(Exception::ParseError,
1875 "src attribute of box-icon element is mandatory - ignoring");
1877 if (!m_data.m_icon.empty()) {
1878 ThrowMsg(Exception::ParseError,
1879 "<tizen:box-icon /> element should occur as 0 or 1 time");
1881 m_data.m_icon = m_icon;
1884 explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1886 m_properNamespace(false),
1892 bool m_properNamespace;
1893 ConfigParserData::LiveboxInfo& m_data;
1896 struct BoxContentParser : public ElementParser
1898 struct BoxSizeParser : public ElementParser
1900 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1901 const DPL::String& /*name*/)
1903 return &IgnoringParser::Create; //ignore unknown according to w3c
1906 virtual void Accept(const XmlAttribute& attribute)
1908 if (m_properNamespace) {
1909 if (attribute.name == L"preview") {
1910 m_preview = attribute.value;
1912 if (attribute.name == L"use-decoration") {
1913 m_useDecoration = attribute.value;
1918 virtual void Accept(const Element& element)
1921 ConfigurationNamespace::TizenWebAppNamespaceName)
1923 m_properNamespace = true;
1927 virtual void Accept(const Text& text)
1929 if (m_properNamespace) {
1930 m_size = text.value;
1934 virtual void Verify()
1936 if(m_size.empty()) {
1937 ThrowMsg(Exception::ParseError,
1938 "size is mandatory - ignoring");
1941 if (m_useDecoration.empty() || CheckIfNotTrueNorFalse(m_useDecoration)) {
1942 m_useDecoration = L"true"; // default value
1945 ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
1946 boxSizeInfo.m_size = m_size;
1947 boxSizeInfo.m_preview = m_preview;
1948 boxSizeInfo.m_useDecoration = m_useDecoration;
1949 m_data.m_boxSize.push_back(boxSizeInfo);
1952 explicit BoxSizeParser(
1953 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1955 m_properNamespace(false),
1961 DPL::String m_preview;
1962 DPL::String m_useDecoration;
1963 bool m_properNamespace;
1964 ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1967 struct PdParser : public ElementParser
1969 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1970 const DPL::String& /*name*/)
1972 return &IgnoringParser::Create; //ignore unknown according to w3c
1975 virtual void Accept(const XmlAttribute& attribute)
1977 if (m_properNamespace) {
1978 if (attribute.name == L"src") {
1979 m_src = attribute.value;
1980 } else if (attribute.name == L"width") {
1981 m_width = attribute.value;
1982 } else if (attribute.name == L"height") {
1983 m_height = attribute.value;
1984 } else if (attribute.name == L"fast-open") {
1985 m_fastOpen= attribute.value;
1990 virtual void Accept(const Element& element)
1993 ConfigurationNamespace::TizenWebAppNamespaceName)
1995 m_properNamespace = true;
1999 virtual void Accept(const Text& /*text*/)
2002 virtual void Verify()
2004 if (m_src.empty()) {
2005 ThrowMsg(Exception::ParseError,
2006 "src attribute of pd element is mandatory - ignoring");
2009 if (m_width.empty()) {
2010 ThrowMsg(Exception::ParseError,
2011 "width attribute of pd element is mandatory - ignoring");
2014 if (m_height.empty()) {
2015 ThrowMsg(Exception::ParseError,
2016 "height attribute of pd element is mandatory - ignoring");
2019 if (!ConvertToInt(m_width)) {
2020 ThrowMsg(Exception::ParseError,
2021 "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
2025 DPL::OptionalInt height = ConvertToInt(m_height);
2028 ThrowMsg(Exception::ParseError,
2029 "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
2034 _D("height attribute of pd element shouldn't be less than 1. Changed to 1 from %d", *height);
2035 } else if (*height > 380){
2037 _D("height attribute of pd element shouldn't be greater than 380. Changed to 380 from %d", *height);
2040 if (!m_data.m_pdSrc.empty()) {
2041 ThrowMsg(Exception::ParseError, "<tizen:pd> element should occur as 0 or 1 time");
2044 m_data.m_pdSrc = m_src;
2045 m_data.m_pdWidth = m_width;
2046 m_data.m_pdHeight = m_height;
2047 m_data.m_pdFastOpen = m_fastOpen;
2051 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
2053 m_properNamespace(false),
2058 DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
2061 std::string tempStr = DPL::ToUTF8String(intAsString);
2062 const char * intAsString_c = tempStr.c_str();
2064 long int intAsString_i = strtol(intAsString_c, &endptr, 10);
2066 if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
2067 || intAsString_i > INT_MAX || intAsString_i < INT_MIN //Intended code for INT_MAX/MIN
2068 || *endptr != '\0') {
2069 return DPL::OptionalInt();
2072 return static_cast<int>(intAsString_i);
2076 DPL::String m_width;
2077 DPL::String m_height;
2078 DPL::String m_fastOpen;
2080 bool m_properNamespace;
2081 ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
2084 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2085 const DPL::String& name)
2087 if (name == L"box-size") {
2088 return std::bind(&AppWidgetParser::BoxContentParser::OnBoxSizeElement, this);
2089 } else if (name == L"pd") {
2090 return std::bind(&AppWidgetParser::BoxContentParser::OnPdElement, this);
2092 ThrowMsg(Exception::ParseError,
2093 "No element parser for name: " << name);
2097 virtual void Accept(const XmlAttribute& attribute)
2099 if (m_properNamespace) {
2100 if (attribute.name == L"src") {
2101 m_box.m_boxSrc = attribute.value;
2103 if (attribute.name == L"mouse-event") {
2104 m_box.m_boxMouseEvent = attribute.value;
2106 if (attribute.name == L"touch-effect") {
2107 m_box.m_boxTouchEffect = attribute.value;
2112 virtual void Accept(const Element& element)
2115 ConfigurationNamespace::TizenWebAppNamespaceName)
2117 m_properNamespace = true;
2121 virtual void Accept(const Text& /*text*/)
2124 virtual void Verify()
2126 if (m_box.m_boxSrc.empty()) {
2127 ThrowMsg(Exception::ParseError,
2128 "src attribute of box-content element is mandatory - ignoring");
2131 if (m_box.m_boxMouseEvent.empty() || CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent)) {
2132 m_box.m_boxMouseEvent = L"false"; // default value
2135 if (m_box.m_boxTouchEffect.empty() || CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect)) {
2136 m_box.m_boxTouchEffect = L"true"; // default value
2139 if (m_box.m_boxSize.empty()) {
2140 ThrowMsg(Exception::ParseError,
2141 "box-size element of box-content element not found - ignoring");
2144 if (!m_data.m_boxInfo.m_boxSrc.empty()) {
2145 ThrowMsg(Exception::ParseError, "<tizen:box-content> element must occur exactly 1 time");
2148 m_data.m_boxInfo = m_box;
2151 explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
2153 m_properNamespace(false),
2157 ElementParserPtr OnBoxSizeElement()
2159 return ElementParserPtr(new BoxSizeParser(m_box));
2162 ElementParserPtr OnPdElement()
2164 return ElementParserPtr(new PdParser(m_box));
2168 bool m_properNamespace;
2169 ConfigParserData::LiveboxInfo& m_data;
2170 ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
2173 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2174 const DPL::String& name)
2176 if (name == L"box-label") {
2177 return std::bind(&AppWidgetParser::OnBoxLabelElement, this);
2178 } else if (name == L"box-icon") {
2179 return std::bind(&AppWidgetParser::OnBoxIconElement, this);
2180 } else if (name == L"box-content") {
2181 return std::bind(&AppWidgetParser::OnBoxContentElement, this);
2183 return &IgnoringParser::Create; //ignore unknown according to w3c
2187 virtual void Accept(const XmlAttribute& attribute)
2189 if (m_properNamespace) {
2190 if (attribute.name == L"id") {
2191 m_liveboxId = attribute.value;
2192 } else if (attribute.name == L"primary") {
2193 m_primary = attribute.value;
2194 } else if (attribute.name == L"auto-launch") {
2195 m_autoLaunch = attribute.value;
2196 } else if (attribute.name == L"update-period") {
2197 m_updatePeriod = attribute.value;
2198 } else if (attribute.name == L"type") {
2199 m_type = attribute.value;
2204 virtual void Accept(const Element& element)
2207 ConfigurationNamespace::TizenWebAppNamespaceName)
2209 m_properNamespace = true;
2213 virtual void Accept(const Text& /*text*/)
2216 virtual void Verify()
2218 if (m_liveboxId.empty()) {
2219 ThrowMsg(Exception::ParseError,
2220 "app-widget element must have id attribute");
2224 pcrecpp::RE re(REGEXP_ID_STRING.c_str());
2225 if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
2227 ThrowMsg(Exception::ParseError,
2228 "invalid format of app-widget id attribute");
2232 if (m_primary.empty() || CheckIfNotTrueNorFalse(m_primary))
2234 m_primary = L"true"; // default value
2237 if (!m_updatePeriod.empty())
2241 std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
2243 //set standard locale to fix decimal point mark - '.'
2244 std::string currentLocale = setlocale(LC_NUMERIC, NULL);
2245 if (NULL == setlocale(LC_NUMERIC, "C"))
2246 _W("Failed to change locale to \"C\"");
2247 double updatePeriod = strtod(tempStr.c_str(), &endptr);
2249 //go back to previous locale
2250 if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
2251 _W("Failed to set previous locale");
2253 if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
2254 || *endptr != '\0') {
2255 ThrowMsg(Exception::ParseError,
2256 "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
2257 } else if (updatePeriod < 1800.0) {
2258 _D("update-period attribute of app-widget element shouldn't be less than 1800.0 - changed to 1800 from value: %ls", m_updatePeriod.c_str());
2259 m_updatePeriod = L"1800.0";
2263 if (m_autoLaunch.empty() || CheckIfNotTrueNorFalse(m_autoLaunch))
2265 m_autoLaunch = L"false"; // default value
2268 if(m_livebox.m_label.empty()) {
2269 ThrowMsg(Exception::ParseError,
2270 "box-label element of app-widget element not found - ignoring");
2273 if(!m_boxContentFound) {
2274 ThrowMsg(Exception::ParseError,
2275 "box-content element of app-widget element not found - ignoring");
2278 m_livebox.m_liveboxId = m_liveboxId;
2279 m_livebox.m_primary = m_primary;
2280 m_livebox.m_autoLaunch = m_autoLaunch;
2281 m_livebox.m_updatePeriod = m_updatePeriod;
2282 m_livebox.m_type = m_type;
2284 m_data.m_livebox.push_back(m_livebox);
2287 explicit AppWidgetParser(ConfigParserData& data) :
2290 m_properNamespace(false),
2291 m_boxContentFound(false)
2293 m_livebox = ConfigParserData::LiveboxInfo();
2296 ElementParserPtr OnBoxLabelElement()
2299 return ElementParserPtr(new BoxLabelParser(m_livebox));
2302 ElementParserPtr OnBoxIconElement()
2304 return ElementParserPtr(new BoxIconParser(m_livebox));
2307 ElementParserPtr OnBoxContentElement()
2309 m_boxContentFound = true;
2310 return ElementParserPtr(new BoxContentParser(m_livebox));
2314 static std::string REGEXP_ID_STRING;
2315 ConfigParserData& m_data;
2316 ConfigParserData::LiveboxInfo m_livebox;
2317 DPL::String m_liveboxId;
2318 DPL::String m_primary;
2319 DPL::String m_autoLaunch;
2320 DPL::String m_updatePeriod;
2322 bool m_properNamespace;
2323 bool m_boxContentFound;
2325 static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
2327 return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
2331 std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
2334 class AllowNavigationParser : public ElementParser
2337 AllowNavigationParser(ConfigParserData& data) :
2340 m_properNamespace(false)
2343 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2344 const DPL::String& /*name*/)
2346 return &IgnoringParser::Create; //ignore unknown according to w3c
2349 virtual void Accept(const Element& element)
2351 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2352 m_properNamespace = true;
2356 virtual void Accept(const Text& text)
2358 if (m_properNamespace)
2360 m_origin = text.value;
2364 virtual void Accept(const XmlAttribute& /*attribute*/)
2368 virtual void Verify()
2370 if (m_data.allowNavigationEncountered || !m_properNamespace)
2374 m_data.allowNavigationEncountered = true;
2377 _W("data is empty");
2381 char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
2382 char* saveptr = NULL;
2383 char* ptr = strtok_r(data," \n\r\t", &saveptr);
2384 while (ptr != NULL) {
2385 std::string origin = ptr;
2386 ptr = strtok_r(NULL," \n\r\t", &saveptr);
2388 ConfigParserData::AllowNavigationInfo info(L"*", L"*");
2389 m_data.allowNavigationInfoList.push_back(info);
2393 std::unique_ptr<iri_t, decltype(&iri_destroy)> iri(iri_parse(origin.c_str()), iri_destroy);
2394 if (!iri->host || strlen(iri->host) == 0) {
2395 // input origin should has schem and host
2396 // in case of file scheme path is filled
2398 _W("input origin isn't verified");
2401 DPL::String scheme = L"*";
2402 if (iri->scheme && strlen(iri->scheme) != 0) {
2403 scheme = DPL::FromUTF8String(iri->scheme);
2405 ConfigParserData::AllowNavigationInfo info(
2407 DPL::FromUTF8String(iri->host));
2408 m_data.allowNavigationInfoList.push_back(info);
2414 DPL::OptionalString m_origin;
2415 ConfigParserData& m_data;
2416 bool m_properNamespace;
2419 class CspParser : public ElementParser
2422 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2423 const DPL::String& /*name*/)
2425 return &IgnoringParser::Create; //ignore unknown according to w3c
2428 CspParser(ConfigParserData& data) :
2431 m_properNamespace(false)
2434 virtual void Accept(const Element& element)
2436 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2437 m_properNamespace = true;
2441 virtual void Accept(const XmlAttribute& /*attribute*/)
2444 virtual void Accept(const Text& text)
2446 if (m_properNamespace) {
2447 m_policy = text.value;
2451 virtual void Verify()
2453 if (m_data.cspPolicyEncountered) {
2456 m_data.cspPolicyEncountered = true;
2459 m_data.cspPolicy = *m_policy;
2464 ConfigParserData& m_data;
2465 bool m_properNamespace;
2466 DPL::OptionalString m_policy;
2469 class CspReportOnlyParser : public ElementParser
2472 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2473 const DPL::String& /*name*/)
2475 return &IgnoringParser::Create; //ignore unknown according to w3c
2478 CspReportOnlyParser(ConfigParserData& data) :
2481 m_properNamespace(false)
2484 virtual void Accept(const Element& element)
2486 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2487 m_properNamespace = true;
2491 virtual void Accept(const XmlAttribute& /*attribute*/)
2494 virtual void Accept(const Text& text)
2496 if (m_properNamespace) {
2497 m_policy = text.value;
2501 virtual void Verify()
2503 if (m_data.cspPolicyReportOnlyEncountered) {
2506 m_data.cspPolicyReportOnlyEncountered = true;
2509 m_data.cspPolicyReportOnly = *m_policy;
2514 ConfigParserData& m_data;
2515 bool m_properNamespace;
2516 DPL::OptionalString m_policy;
2519 class AccountParser : public ElementParser
2522 struct IconParser : public ElementParser
2525 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2526 const DPL::String& /*name*/)
2528 return &IgnoringParser::Create; //ignore unknown according to w3c
2531 virtual void Accept(const Text& text)
2533 if (text.value == L"") {
2536 m_value = text.value;
2539 virtual void Accept(const Element& /*element*/)
2542 virtual void Accept(const XmlAttribute& attribute)
2544 if (attribute.name == L"section") {
2545 if (attribute.value == L"Account") {
2546 m_type = ConfigParserData::IconSectionType::DefaultIcon;
2547 } else if (attribute.value == L"AccountSmall") {
2548 m_type = ConfigParserData::IconSectionType::SmallIcon;
2553 virtual void Verify()
2555 if (!m_value || *m_value == L"") {
2559 std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2560 icon.first = m_type;
2561 icon.second = *m_value;
2563 m_data.m_iconSet.insert(icon);
2566 IconParser(ConfigParserData::AccountProvider& data) :
2568 m_properNamespace(false),
2569 m_type(ConfigParserData::DefaultIcon),
2574 bool m_properNamespace;
2575 ConfigParserData::IconSectionType m_type;
2576 ConfigParserData::AccountProvider& m_data;
2577 DPL::OptionalString m_value;
2580 struct DisplayNameParser : public ElementParser
2583 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2584 const DPL::String& /*name*/)
2586 return &IgnoringParser::Create; //ignore unknown according to w3c
2589 virtual void Accept(const Text& text)
2591 if (text.value == L"") {
2594 m_value = text.value;
2597 virtual void Accept(const Element& element)
2599 m_lang = element.lang;
2603 virtual void Accept(const XmlAttribute& /*attribute*/)
2606 virtual void Verify()
2608 if (!m_value || *m_value == L"") {
2612 std::pair<DPL::String, DPL::String> name;
2613 name.first = *m_lang;
2614 name.second = *m_value;
2616 m_data.m_displayNameSet.insert(name);
2619 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2621 m_properNamespace(false),
2626 bool m_properNamespace;
2627 DPL::OptionalString m_lang;
2628 DPL::OptionalString m_value;
2629 ConfigParserData::AccountProvider& m_data;
2632 struct CapabilityParser : public ElementParser
2635 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2636 const DPL::String& /*name*/)
2638 return &IgnoringParser::Create; //ignore unknown according to w3c
2641 virtual void Accept(const Text& text)
2643 if (text.value == L"") {
2646 m_value = text.value;
2649 virtual void Accept(const Element& /*element*/)
2652 virtual void Accept(const XmlAttribute& /*attribute*/)
2655 virtual void Verify()
2657 if (!m_value || *m_value == L"") {
2660 m_data.m_capabilityList.push_back(*m_value);
2663 CapabilityParser(ConfigParserData::AccountProvider& data) :
2665 m_properNamespace(false),
2670 bool m_properNamespace;
2671 DPL::OptionalString m_value;
2672 ConfigParserData::AccountProvider& m_data;
2674 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2675 const DPL::String& name)
2677 if (name == L"icon") {
2678 return std::bind(&AccountParser::OnIconElement, this);
2679 } else if (name == L"display-name") {
2680 return std::bind(&AccountParser::OnDisplayNameElement, this);
2681 } else if (name == L"capability") {
2682 return std::bind(&AccountParser::OnCapabilityElement, this);
2684 return &IgnoringParser::Create; //ignore unknown according to w3c
2688 virtual void Accept(const Text& /*text*/)
2691 virtual void Accept(const Element& /*element*/)
2694 virtual void Accept(const XmlAttribute& attribute)
2696 if (attribute.name == L"multiple-account-support") {
2697 if (attribute.value == L"true") {
2698 m_account.m_multiAccountSupport = true;
2703 virtual void Verify()
2707 ElementParserPtr OnIconElement()
2709 return ElementParserPtr(new IconParser(m_account));
2712 ElementParserPtr OnDisplayNameElement()
2714 return ElementParserPtr(new DisplayNameParser(m_account));
2717 ElementParserPtr OnCapabilityElement()
2719 return ElementParserPtr(new CapabilityParser(m_account));
2722 AccountParser(ConfigParserData& data) :
2724 m_properNamespace(false),
2725 m_multiSupport(false),
2727 m_account(data.accountProvider)
2732 bool m_properNamespace;
2733 bool m_multiSupport;
2734 ConfigParserData& m_data;
2735 ConfigParserData::AccountProvider& m_account;
2738 class MetadataParser : public ElementParser
2741 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2742 const DPL::String& /*name*/)
2744 return &IgnoringParser::Create; //ignore unknown according to w3c
2747 virtual void Accept(const XmlAttribute& attribute)
2749 if (m_properNamespace) {
2750 if (attribute.name == L"key") {
2751 m_key = attribute.value;
2752 } else if (attribute.name == L"value") {
2753 m_value = attribute.value;
2758 virtual void Accept(const Element& element)
2760 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2761 m_properNamespace = true;
2765 virtual void Accept(const Text& /*text*/)
2767 ThrowMsg(Exception::ParseError, "param element must be empty");
2770 virtual void Verify()
2773 _W("metadata element must have key attribute");
2776 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
2777 NormalizeString(m_key, MAX_NAME_KEY_LENGTH, true);
2778 NormalizeString(m_value, MAX_NAME_KEY_VALUE_LENGTH, true);
2780 NormalizeString(m_key);
2781 NormalizeString(m_value);
2783 ConfigParserData::Metadata metaData(m_key, m_value);
2784 FOREACH(it, m_data.metadataList) {
2785 if (!DPL::StringCompare(*it->key, *m_key)) {
2786 _E("Key isn't unique");
2790 m_data.metadataList.push_back(metaData);
2793 MetadataParser(ConfigParserData& data) :
2796 m_properNamespace(false)
2800 DPL::OptionalString m_key;
2801 DPL::OptionalString m_value;
2802 ConfigParserData& m_data;
2803 bool m_properNamespace;
2807 class ImeParser : public ElementParser
2810 struct UuidParser : public ElementParser
2813 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2814 const DPL::String& /*name*/)
2816 return &IgnoringParser::Create;
2819 virtual void Accept(const XmlAttribute& /*attribute*/)
2822 virtual void Accept(const Element& /*element*/)
2825 virtual void Accept(const Text& text)
2827 if (m_uuid.empty()) {
2828 m_uuid = text.value;
2830 m_uuid += text.value;
2834 virtual void Verify()
2836 if (m_uuid.empty()) {
2837 ThrowMsg(Exception::ParseError, "uuid text is empty");
2840 if (uuid_parse(DPL::ToUTF8String(m_uuid).c_str(), uu)){
2841 ThrowMsg(Exception::ParseError, "invalid uuid");
2843 m_imeAppInfo.uuid = m_uuid;
2846 UuidParser(ConfigParserData::ImeAppInfo& data) :
2852 ConfigParserData::ImeAppInfo& m_imeAppInfo;
2856 struct LanguagesParser : public ElementParser
2859 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2860 const DPL::String& name)
2862 if (name == L"language") {
2863 return std::bind(&LanguagesParser::OnLanguageElement, this);
2865 return &IgnoringParser::Create;
2869 virtual void Accept(const XmlAttribute& /*attribute*/)
2872 virtual void Accept(const Element& /*element*/)
2875 virtual void Accept(const Text& /*text*/)
2877 ThrowMsg(Exception::ParseError, "param element must be empty");
2880 virtual void Verify()
2883 LanguagesParser(ConfigParserData::ImeAppInfo& data) :
2888 ElementParserPtr OnLanguageElement()
2890 return ElementParserPtr(new LanguageParser(m_imeAppInfo));
2894 ConfigParserData::ImeAppInfo& m_imeAppInfo;
2897 struct LanguageParser : public ElementParser
2900 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2901 const DPL::String& /*name*/)
2903 return &IgnoringParser::Create;
2906 virtual void Accept(const XmlAttribute& /*attribute*/)
2909 virtual void Accept(const Element& /*element*/)
2912 virtual void Accept(const Text& text)
2914 if (m_language.empty()) {
2915 m_language = text.value;
2917 m_language += text.value;
2921 virtual void Verify()
2923 if (m_language.empty()) {
2924 ThrowMsg(Exception::ParseError, "language text is empty");
2926 m_imeAppInfo.languageList.insert(m_language);
2929 LanguageParser(ConfigParserData::ImeAppInfo& data) :
2935 ConfigParserData::ImeAppInfo& m_imeAppInfo;
2936 DPL::String m_language;
2939 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2940 const DPL::String& name)
2942 if (name == L"uuid") {
2944 return std::bind(&ImeParser::OnUuidElement, this);
2945 } else if (name == L"languages") {
2946 m_languagesTagCount++;
2947 return std::bind(&ImeParser::OnLanguagesElement, this);
2949 return &IgnoringParser::Create;
2953 virtual void Accept(const Text& /*text*/)
2955 ThrowMsg(Exception::ParseError, "param element must be empty");
2958 virtual void Accept(const Element& /*element*/)
2961 virtual void Accept(const XmlAttribute& /*attribute*/)
2964 virtual void Verify()
2966 if (m_imeAppInfo.uuid.empty()) {
2967 ThrowMsg(Exception::ParseError, "ime element must have uuid element");
2971 if (m_imeAppInfo.languageList.empty()) {
2972 ThrowMsg(Exception::ParseError, "ime element must have language element");
2976 if (m_uuidTagCount > 1) {
2977 ThrowMsg(Exception::ParseError, "As per Tizen 2.3 wrt core spec, occurence of uuid must be 1");
2980 if (m_languagesTagCount > 1) {
2981 ThrowMsg(Exception::ParseError, "As per Tizen 2.3 wrt core spec, occurence of languages must be 1");
2983 m_data.imeAppInfoList.push_back(m_imeAppInfo);
2986 ImeParser(ConfigParserData& data) :
2991 m_languagesTagCount(0)
2994 ElementParserPtr OnLanguagesElement()
2996 return ElementParserPtr(new LanguagesParser(m_imeAppInfo));
2999 ElementParserPtr OnUuidElement()
3001 return ElementParserPtr(new UuidParser(m_imeAppInfo));
3005 ConfigParserData& m_data;
3006 ConfigParserData::ImeAppInfo m_imeAppInfo;
3007 unsigned char m_uuidTagCount;
3008 unsigned char m_languagesTagCount;
3012 #ifdef SERVICE_ENABLED
3013 class ServiceAppParser : public ElementParser
3016 struct ServiceContentParser : public ElementParser
3018 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
3019 const DPL::String& /*name*/)
3021 return &IgnoringParser::Create; //ignore unknown according to w3c
3024 virtual void Accept(const XmlAttribute& attribute)
3026 if (attribute.name == L"src") {
3027 m_src = attribute.value;
3031 virtual void Accept(const Element& /*element*/)
3034 virtual void Accept(const Text& /*text*/)
3036 ThrowMsg(Exception::ParseError, "param element must be empty");
3039 virtual void Verify()
3041 if (m_src.empty()) {
3042 ThrowMsg(Exception::ParseError, "src attribute of content element is mandatory");
3045 if (!m_serviceAppInfo.serviceContent.empty()) {
3046 ThrowMsg(Exception::ParseError, "content element occurs more than 1 time");
3048 m_serviceAppInfo.serviceContent = m_src;
3051 explicit ServiceContentParser(ConfigParserData::ServiceAppInfo& data) :
3053 m_serviceAppInfo(data)
3058 ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
3061 struct ServiceNameParser : public ElementParser
3063 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
3064 const DPL::String& /*name*/)
3066 return &IgnoringParser::Create;
3069 virtual void Accept(const XmlAttribute& attribute)
3071 m_lang = attribute.lang;
3074 virtual void Accept(const Element& /*element*/)
3077 virtual void Accept(const Text& text)
3079 m_name = text.value;
3082 virtual void Verify()
3084 ConfigParserData::LocalizedData& data = m_serviceAppInfo.m_localizedDataSet[m_lang];
3087 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3088 NormalizeString(m_name, MAX_ATTR_ELEMENT_LENGTH, true);
3090 NormalizeString(m_name);
3097 ServiceNameParser(ConfigParserData::ServiceAppInfo& data) :
3099 m_serviceAppInfo(data)
3104 DPL::OptionalString m_name;
3105 ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
3108 struct ServiceIconParser : public ElementParser
3110 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
3111 const DPL::String& /*name*/)
3113 return &IgnoringParser::Create;
3116 virtual void Accept(const XmlAttribute& attribute)
3118 if (attribute.name == L"src") {
3119 m_icon.src = attribute.value;
3121 else if (attribute.name == L"width") {
3122 m_icon.width = ParseSizeAttributeValue(attribute.value);
3124 else if (attribute.name == L"height") {
3125 m_icon.height = ParseSizeAttributeValue(attribute.value);
3129 virtual void Accept(const Element& /*element*/)
3132 virtual void Accept(const Text& /*text*/)
3134 ThrowMsg(Exception::ParseError, "param element must be empty");
3137 virtual void Verify()
3139 if (m_icon.src.empty()) {
3140 ThrowMsg(Exception::ParseError,
3141 "src attribute of icon element is mandatory - ignoring");
3143 m_serviceAppInfo.m_iconsList.push_back(m_icon);
3146 explicit ServiceIconParser(ConfigParserData::ServiceAppInfo& data) :
3149 m_serviceAppInfo(data)
3153 ConfigParserData::Icon m_icon;
3154 ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
3156 static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
3158 DPL::OptionalString normalizedValue = value;
3159 NormalizeString(normalizedValue);
3160 if (!(*normalizedValue).empty()) {
3161 char* reterr = NULL;
3163 long int valueInt = strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
3164 if (errno != 0 || std::string(reterr) == DPL::ToUTF8String(value) || valueInt <= 0) {
3165 return DPL::OptionalInt();
3170 return DPL::OptionalInt();
3174 struct ServiceDescriptionParser : public ElementParser
3176 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, const DPL::String& /*name*/)
3178 return &IgnoringParser::Create; //ignore unknown according to w3c
3181 virtual void Accept(const XmlAttribute& attribute)
3183 m_lang = attribute.lang;
3186 virtual void Accept(const Element& /*element*/)
3189 virtual void Accept(const Text& text)
3191 m_description = text.value;
3194 virtual void Verify()
3196 ConfigParserData::LocalizedData& data = m_serviceAppInfo.m_localizedDataSet[m_lang];
3197 if (!data.description) {
3198 data.description = m_description;
3202 ServiceDescriptionParser(ConfigParserData::ServiceAppInfo& data) :
3204 m_serviceAppInfo(data)
3209 DPL::OptionalString m_description;
3210 ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
3213 struct ServiceMetadataParser : public ElementParser
3215 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, const DPL::String& /*name*/)
3217 return &IgnoringParser::Create; //ignore unknown according to w3c
3220 virtual void Accept(const XmlAttribute& attribute)
3222 if (attribute.name == L"key") {
3223 m_key = attribute.value;
3224 } else if (attribute.name == L"value") {
3225 m_value = attribute.value;
3229 virtual void Accept(const Element& /*element*/)
3232 virtual void Accept(const Text& /*text*/)
3234 ThrowMsg(Exception::ParseError, "param element must be empty");
3237 virtual void Verify()
3240 _W("metadata element must have key attribute");
3243 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3244 NormalizeString(m_key, MAX_NAME_KEY_LENGTH, true);
3245 NormalizeString(m_value, MAX_NAME_KEY_VALUE_LENGTH, true);
3247 NormalizeString(m_key);
3248 NormalizeString(m_value);
3250 ConfigParserData::Metadata metaData(m_key, m_value);
3251 FOREACH(it, m_serviceAppInfo.m_metadataList) {
3252 if (!DPL::StringCompare(*it->key, *m_key)) {
3253 _E("Key isn't unique");
3257 m_serviceAppInfo.m_metadataList.push_back(metaData);
3260 ServiceMetadataParser(ConfigParserData::ServiceAppInfo& data) :
3262 m_serviceAppInfo(data)
3266 DPL::OptionalString m_key;
3267 DPL::OptionalString m_value;
3268 ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
3271 struct ServiceCategoryParser : public ElementParser
3273 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/, const DPL::String& /*name*/)
3275 return &IgnoringParser::Create; //ignore unknown according to w3c
3278 virtual void Accept(const XmlAttribute& attribute)
3280 if (attribute.name == L"name") {
3281 if (attribute.value.size() > 0) {
3282 m_name = attribute.value;
3287 virtual void Accept(const Element& /*element*/)
3290 virtual void Accept(const Text& /*text*/)
3292 ThrowMsg(Exception::ParseError, "param element must be empty");
3295 virtual void Verify()
3298 _W("name attribute of category element is mandatory - ignoring");
3302 if (m_serviceAppInfo.m_categoryList.find(*m_name) == m_serviceAppInfo.m_categoryList.end()) {
3303 m_serviceAppInfo.m_categoryList.insert(*m_name);
3307 ServiceCategoryParser(ConfigParserData::ServiceAppInfo& data) :
3309 m_serviceAppInfo(data)
3313 DPL::OptionalString m_name;
3314 ConfigParserData::ServiceAppInfo& m_serviceAppInfo;
3317 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
3318 const DPL::String& name)
3320 if (name == L"content") {
3321 return std::bind(&ServiceAppParser::OnServiceContentElement, this);
3322 } else if (name == L"name") {
3323 return std::bind(&ServiceAppParser::OnServiceNameElement, this);
3324 } else if (name == L"icon") {
3325 return std::bind(&ServiceAppParser::OnServiceIconElement, this);
3326 } else if (name == L"description") {
3327 return std::bind(&ServiceAppParser::OnServiceDescriptionElement, this);
3328 } else if (name == L"metadata") {
3329 return std::bind(&ServiceAppParser::OnServiceMetadataElement, this);
3330 } else if (name == L"category") {
3331 return std::bind(&ServiceAppParser::OnServiceCategoryElement, this);
3333 return &IgnoringParser::Create;
3337 virtual void Accept(const Element& /*element*/)
3340 virtual void Accept(const XmlAttribute& attribute)
3342 if (attribute.name == L"id") {
3343 if (attribute.value.size() > 0) {
3344 m_serviceId = attribute.value;
3346 } else if (attribute.name == L"auto-restart") {
3347 if (attribute.value == L"true") {
3348 m_autoRestart = true;
3349 } else if (attribute.value == L"false") {
3350 m_autoRestart = false;
3352 ThrowMsg(Exception::ParseError, "Wrong boolean value");
3354 } else if (attribute.name == L"on-boot") {
3355 if (attribute.value == L"true") {
3357 } else if (attribute.value == L"false") {
3360 ThrowMsg(Exception::ParseError, "Wrong boolean value");
3365 virtual void Accept(const Text& /*text*/)
3367 ThrowMsg(Exception::ParseError, "param element must be empty");
3370 virtual void Verify()
3372 FOREACH(it, m_data.settingsList) {
3373 if (it->m_name == L"encryption" && it->m_value == L"enable") {
3374 ThrowMsg(Exception::ParseError, "Service application does not support application encryption");
3378 if (m_serviceAppInfo.serviceContent.empty()) {
3379 ThrowMsg(Exception::ParseError, "service element must have content element");
3382 if (m_serviceId.empty()) {
3383 ThrowMsg(Exception::ParseError, "service attribute must have id attribute");
3386 m_serviceAppInfo.serviceId = m_serviceId;
3388 m_serviceAppInfo.autoRestart = m_autoRestart;
3390 m_serviceAppInfo.onBoot = m_onBoot;
3392 m_data.serviceAppInfoList.push_back(m_serviceAppInfo);
3395 ServiceAppParser(ConfigParserData& data) :
3397 m_autoRestart(false),
3403 ElementParserPtr OnServiceContentElement()
3405 return ElementParserPtr(new ServiceContentParser(m_serviceAppInfo));
3408 ElementParserPtr OnServiceNameElement()
3410 return ElementParserPtr(new ServiceNameParser(m_serviceAppInfo));
3413 ElementParserPtr OnServiceIconElement()
3415 return ElementParserPtr(new ServiceIconParser(m_serviceAppInfo));
3418 ElementParserPtr OnServiceDescriptionElement()
3420 return ElementParserPtr(new ServiceDescriptionParser(m_serviceAppInfo));
3423 ElementParserPtr OnServiceMetadataElement()
3425 return ElementParserPtr(new ServiceMetadataParser(m_serviceAppInfo));
3428 ElementParserPtr OnServiceCategoryElement()
3430 return ElementParserPtr(new ServiceCategoryParser(m_serviceAppInfo));
3436 DPL::String m_serviceId;
3437 ConfigParserData& m_data;
3438 ConfigParserData::ServiceAppInfo m_serviceAppInfo;
3442 ElementParser::ActionFunc WidgetParser::GetElementParser(
3443 const DPL::String& /*ns*/,
3444 const DPL::String& name)
3446 FuncMap::const_iterator it = m_map.find(name);
3447 if (it != m_map.end()) {
3450 return &IgnoringParser::Create; //ignore unknown according to w3c
3454 WidgetParser::WidgetParser(ConfigParserData& data) :
3456 m_textDirection(Unicode::EMPTY)
3458 m_map[L"name"] = std::bind(&WidgetParser::OnNameElement, this);
3459 m_map[L"access"] = std::bind(&WidgetParser::OnAccessElement, this);
3460 m_map[L"description"] = std::bind(&WidgetParser::OnDescriptionElement, this);
3461 m_map[L"author"] = std::bind(&WidgetParser::OnAuthorElement, this);
3462 m_map[L"license"] = std::bind(&WidgetParser::OnLicenseElement, this);
3463 m_map[L"icon"] = std::bind(&WidgetParser::OnIconElement, this);
3464 m_map[L"small-icon"] = std::bind(&WidgetParser::OnSmallIconElement, this);
3465 m_map[L"content"] = std::bind(&WidgetParser::OnContentElement, this);
3466 m_map[L"preference"] = std::bind(&WidgetParser::OnPreferenceElement, this);
3467 m_map[L"setting"] = std::bind(&WidgetParser::OnSettingElement, this);
3468 m_map[L"application"] = std::bind(&WidgetParser::OnApplicationElement, this);
3470 m_map[L"ime"] = std::bind(&WidgetParser::OnImeElement, this);
3472 #ifdef SERVICE_ENABLED
3473 m_map[L"service"] = std::bind(&WidgetParser::OnServiceAppElement, this);
3475 m_map[L"splash"] = std::bind(&WidgetParser::OnSplashElement, this);
3476 m_map[L"background"] = std::bind(&WidgetParser::OnBackgroundElement, this);
3477 m_map[L"privilege"] = std::bind(&WidgetParser::OnPrivilegeElement, this);
3478 m_map[L"app-control"] = std::bind(&WidgetParser::OnAppControlElement, this);
3479 m_map[L"category"] = std::bind(&WidgetParser::OnCategoryElement, this);
3480 m_map[L"background-category"] = std::bind(&WidgetParser::OnBackgroundCategoryElement, this);
3481 #if USE(WEB_PROVIDER)
3482 m_map[L"app-widget"] = std::bind(&WidgetParser::OnAppWidgetElement, this);
3484 #if ENABLE(CONTENT_SECURITY_POLICY)
3485 m_map[L"content-security-policy"] = std::bind(&WidgetParser::OnCspElement, this);
3486 m_map[L"content-security-policy-report-only"] = std::bind(&WidgetParser::OnCspReportOnlyElement, this);
3488 #if ENABLE(ALLOW_NAVIGATION)
3489 m_map[L"allow-navigation"] = std::bind(&WidgetParser::OnAllowNavigationElement, this);
3491 m_map[L"account"] = std::bind(&WidgetParser::OnAccountElement, this);
3492 m_map[L"metadata"] = std::bind(&WidgetParser::OnMetadataElement, this);
3495 ElementParserPtr WidgetParser::OnNameElement()
3497 return ElementParserPtr(new NameParser(m_textDirection, m_data));
3500 ElementParserPtr WidgetParser::OnAccessElement()
3502 return ElementParserPtr(new AccessParser(m_data));
3505 ElementParserPtr WidgetParser::OnDescriptionElement()
3507 return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
3510 ElementParserPtr WidgetParser::OnAuthorElement()
3512 return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
3515 ElementParserPtr WidgetParser::OnLicenseElement()
3517 return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
3520 ElementParserPtr WidgetParser::OnIconElement()
3522 return ElementParserPtr(new IconParser(m_data));
3525 ElementParserPtr WidgetParser::OnSmallIconElement()
3527 return ElementParserPtr(new IconParser(m_data, true));
3530 ElementParserPtr WidgetParser::OnContentElement()
3532 return ElementParserPtr(new ContentParser(m_data));
3535 ElementParserPtr WidgetParser::OnPreferenceElement()
3537 return ElementParserPtr(new PreferenceParser(m_data));
3540 ElementParserPtr WidgetParser::OnSettingElement()
3542 return ElementParserPtr(new SettingParser(m_data));
3545 ElementParserPtr WidgetParser::OnApplicationElement()
3547 return ElementParserPtr(new ApplicationParser(m_data));
3550 ElementParserPtr WidgetParser::OnSplashElement()
3552 return ElementParserPtr(new SplashParser(m_data));
3555 ElementParserPtr WidgetParser::OnBackgroundElement()
3557 return ElementParserPtr(new BackgroundParser(m_data));
3560 ElementParserPtr WidgetParser::OnPrivilegeElement()
3562 return ElementParserPtr(new PrivilegeParser(m_data));
3565 ElementParserPtr WidgetParser::OnAppControlElement()
3567 return ElementParserPtr(new AppControlParser(m_data));
3570 ElementParserPtr WidgetParser::OnCategoryElement()
3572 return ElementParserPtr(new CategoryParser(m_data));
3575 ElementParserPtr WidgetParser::OnBackgroundCategoryElement()
3577 return ElementParserPtr(new BackgroundCategoryParser(m_data));
3580 #if USE(WEB_PROVIDER)
3581 ElementParserPtr WidgetParser::OnAppWidgetElement()
3583 return ElementParserPtr(new AppWidgetParser(m_data));
3587 ElementParserPtr WidgetParser::OnCspElement()
3589 return ElementParserPtr(new CspParser(m_data));
3592 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
3594 return ElementParserPtr(new CspReportOnlyParser(m_data));
3597 ElementParserPtr WidgetParser::OnAllowNavigationElement()
3599 return ElementParserPtr(new AllowNavigationParser(m_data));
3602 ElementParserPtr WidgetParser::OnAccountElement()
3604 return ElementParserPtr(new AccountParser(m_data));
3607 ElementParserPtr WidgetParser::OnMetadataElement()
3609 return ElementParserPtr(new MetadataParser(m_data));
3613 ElementParserPtr WidgetParser::OnImeElement()
3615 return ElementParserPtr(new ImeParser(m_data));
3619 #ifdef SERVICE_ENABLED
3620 ElementParserPtr WidgetParser::OnServiceAppElement()
3622 return ElementParserPtr(new ServiceAppParser(m_data));
3626 void WidgetParser::Accept(const Element& element)
3628 if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
3629 element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
3631 ThrowMsg(Exception::ParseError,
3632 "Wrong xml namespace for widget element");
3636 void WidgetParser::Accept(const Text& /*text*/)
3638 ThrowMsg(Exception::ParseError, "widged element must be empty");
3641 void WidgetParser::Accept(const XmlAttribute& attribute)
3643 if (attribute.name == L"id") {
3644 LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
3645 //If may important tests starts to fail this test we will have
3646 //to consider commenting this test out again.
3647 if (iri.Validate()) {
3648 m_widgetId = attribute.value;
3650 _W("Widget id validation failed: %ls", attribute.value.c_str());
3652 } else if (attribute.name == L"version") {
3653 m_version = attribute.value;
3654 } else if (attribute.name == L"min-version") {
3655 _D("min-version attribute was found. Value: %ls", attribute.value.c_str());
3656 m_minVersion = attribute.value;
3657 m_data.minVersionRequired = m_minVersion;
3658 } else if (attribute.name == L"height") {
3659 DPL::OptionalString value = attribute.value;
3660 if (!(*value).empty()) {
3661 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3662 NormalizeString(value, MAX_ATTR_ELEMENT_LENGTH, true);
3664 NormalizeString(value);
3666 std::string v = DPL::ToUTF8String(*value);
3667 unsigned char c = v.c_str()[0];
3670 for (size_t i = 0; i < v.size(); ++i) {
3679 m_data.height = val;
3682 } else if (attribute.name == L"width") {
3683 DPL::OptionalString value = attribute.value;
3684 if (!(*value).empty()) {
3685 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3686 NormalizeString(value, MAX_ATTR_ELEMENT_LENGTH, true);
3688 NormalizeString(value);
3690 std::string v = DPL::ToUTF8String(*value);
3691 unsigned char c = v.c_str()[0];
3692 if (c >= '0' && c <= '9') {
3694 for (size_t i = 0; i < v.size(); ++i) {
3696 if (c >= '0' && c <= '9') {
3706 } else if (attribute.name == L"viewmodes") {
3707 DPL::Tokenize(attribute.value,
3709 std::inserter(m_windowModes,
3710 m_windowModes.end()),
3712 } else if (attribute.name == L"dir") {
3713 m_textDirection = Unicode::ParseDirAttribute(attribute);
3714 } else if (L"defaultlocale" == attribute.name) {
3715 if (!m_defaultlocale) {
3716 m_defaultlocale = attribute.value;
3718 _W("Ignoring subsequent default locale");
3720 //Any other value consider as a namespace definition
3721 } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
3722 _D("Namespace domain: %ls", attribute.name.c_str());
3723 _D("Namespace value: %ls", attribute.value.c_str());
3724 m_nameSpaces[attribute.name] = attribute.value;
3726 _E("Unknown attirbute: namespace=%ls, name=%ls, value=%ls",
3727 attribute.ns.c_str(), attribute.name.c_str(), attribute.value.c_str());
3731 void WidgetParser::Verify()
3733 if (m_data.imeAppInfoList.size() > 1) {
3734 ThrowMsg(Exception::ParseError, "ime element must not be more than one");
3736 } else if (m_data.imeAppInfoList.size() == 1) {
3737 if (m_data.categoryList.end() == m_data.categoryList.find(L"http://tizen.org/category/ime")) {
3738 ThrowMsg(Exception::ParseError,\
3739 "<tizen:category name=\"http://tizen.org/category/ime\"/> should be defined to activate <tizen:ime>");
3743 FOREACH(mode, m_windowModes) {
3744 if (L"windowed" == *mode || L"floating" == *mode ||
3745 L"fullscreen" == *mode || L"maximized" == *mode ||
3746 L"minimized" == *mode)
3748 m_data.windowModes.insert(*mode);
3752 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3753 NormalizeString(m_widgetId, MAX_ATTR_ELEMENT_LENGTH, true);
3755 NormalizeString(m_widgetId);
3757 m_data.widget_id = m_widgetId;
3760 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3761 NormalizeString(m_version, MAX_ATTR_ELEMENT_LENGTH, true);
3763 NormalizeString(m_version);
3765 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
3766 m_data.version = m_version;
3768 if (!!m_minVersion) {
3769 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3770 NormalizeString(m_minVersion, MAX_ATTR_ELEMENT_LENGTH, true);
3772 NormalizeString(m_minVersion);
3774 m_data.minVersionRequired = m_minVersion;
3776 if (!!m_defaultlocale) {
3777 #if ENABLE(ELEMENT_ATTR_MAX_LENGTH)
3778 NormalizeString(m_defaultlocale, MAX_ATTR_ELEMENT_LENGTH, true);
3780 NormalizeString(m_defaultlocale);
3782 std::string dl = DPL::ToUTF8String(*m_defaultlocale);
3784 if (!LanguageSubtagRstTreeSingleton::Instance().
3785 ValidateLanguageTag(dl)) {
3786 _W("Language tag: %s is not valid", dl.c_str());
3787 m_defaultlocale = DPL::OptionalString();
3789 _D("Default locale found %s", dl.c_str());
3791 m_data.defaultlocale = m_defaultlocale;
3793 FOREACH(ns, m_nameSpaces) {
3794 m_data.nameSpaces.insert(ns->second);