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)
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>
37 #include <dpl/log/log.h>
38 #include <dpl/fast_delegate.h>
39 #include <dpl/foreach.h>
40 #include <dpl/scoped_ptr.h>
51 using namespace WrtDB;
54 static const DPL::String UTF_LRE = L"\x0202a";
55 static const DPL::String UTF_LRO = L"\x0202d";
56 static const DPL::String UTF_RLE = L"\x0202b";
57 static const DPL::String UTF_RLO = L"\x0202e";
58 static const DPL::String UTF_PDF = L"\x0202c";
60 Direction ParseDirAttribute(const XmlAttribute& attribute)
62 Assert(L"dir" == attribute.name);
63 if (L"ltr" == attribute.value) {
65 } else if (L"rtl" == attribute.value) {
67 } else if (L"lro" == attribute.value) {
69 } else if (L"rlo" == attribute.value) {
72 LogWarning("dir attribute has wrong value:" << attribute.value);
77 void UpdateTextWithDirectionMark(Direction direction,
83 *text = UTF_RLO + *text + UTF_PDF;
86 *text = UTF_RLE + *text + UTF_PDF;
89 *text = UTF_LRE + *text + UTF_PDF;
92 *text = UTF_LRO + *text + UTF_PDF;
101 } // namespace Unicode
103 class InnerElementsParser : public ElementParser
106 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
107 const DPL::String& /*name*/)
109 return DPL::MakeDelegate(this, &InnerElementsParser::Other);
112 virtual void Accept(const Element& /*element*/)
115 virtual void Accept(const Text& text)
117 if (m_text.IsNull()) {
120 m_text->value += text.value;
124 virtual void Accept(const XmlAttribute& attribute)
126 if (attribute.name == L"dir") {
127 m_textDirection = Unicode::ParseDirAttribute(attribute);
131 virtual void Verify()
133 if (!m_text.IsNull()) {
134 Unicode::UpdateTextWithDirectionMark(m_textDirection,
136 m_parentParser->Accept(*m_text);
140 InnerElementsParser(ElementParserPtr parent) :
141 m_parentParser(parent),
142 m_textDirection(Unicode::EMPTY)
145 ElementParserPtr Other()
147 return ElementParserPtr(new InnerElementsParser(
148 std::static_pointer_cast<ElementParser>(
149 shared_from_this())));
153 DPL::Optional<Text> m_text;
154 ElementParserPtr m_parentParser;
155 Unicode::Direction m_textDirection;
158 class NameParser : public ElementParser
161 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
162 const DPL::String& /*name*/)
164 return DPL::MakeDelegate(this, &NameParser::Other);
167 virtual void Accept(const Element& element)
169 m_lang = element.lang;
173 virtual void Accept(const Text& text)
175 if (m_name.IsNull()) {
178 *m_name += text.value;
182 virtual void Accept(const XmlAttribute& attribute)
184 if (attribute.name == L"short") {
185 if (m_shortName.IsNull()) {
186 m_shortName = attribute.value;
188 } else if (attribute.name == L"dir") {
189 m_textDirection = Unicode::ParseDirAttribute(attribute);
193 virtual void Verify()
195 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
196 if (data.name.IsNull()) {
197 NormalizeString(m_name);
198 NormalizeString(m_shortName);
199 if (!m_name.IsNull()) {
200 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
203 if (!m_shortName.IsNull()) {
204 Unicode::UpdateTextWithDirectionMark(m_textDirection,
207 data.shortName = m_shortName;
211 NameParser(Unicode::Direction direction,
212 ConfigParserData& data) :
214 m_textDirection(direction)
217 ElementParserPtr Other()
219 return ElementParserPtr(new InnerElementsParser(
220 std::static_pointer_cast<ElementParser>(
221 shared_from_this())));
225 ConfigParserData& m_data;
226 DPL::OptionalString m_name;
227 DPL::OptionalString m_shortName;
228 DPL::OptionalString m_dir;
230 Unicode::Direction m_textDirection;
233 class AccessParser : public ElementParser
242 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
243 const DPL::String& /*name*/)
245 return DPL::MakeDelegate(this, &AccessParser::Other);
248 virtual void Accept(const Element& element)
250 // for tizen web apps WARP should be used
251 if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
252 element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
254 m_standardType = STANDARD_TYPE_WARP;
258 virtual void Accept(const Text& /*text*/)
261 void AcceptWac(const XmlAttribute& attribute)
263 if (attribute.name == L"origin") {
264 m_strIRIOrigin = attribute.value;
265 NormalizeString(m_strIRIOrigin);
266 } else if (attribute.name == L"subdomains") {
267 DPL::String normalizedValue = attribute.value;
268 NormalizeString(normalizedValue);
270 if (normalizedValue == L"true") {
271 m_bSubDomainAccess = true;
272 } else if (normalizedValue == L"false") {
273 m_bSubDomainAccess = false;
278 virtual void Accept(const XmlAttribute& attribute)
280 switch (m_standardType) {
281 case STANDARD_TYPE_WARP:
282 AcceptWac(attribute);
285 LogError("Error in Access tag - unknown standard.");
293 iri.set(m_strIRIOrigin, false);
295 if (!iri.isAccessDefinition()) {
296 LogWarning("Access list element: " <<
298 " is not acceptable by WARP" <<
299 "standard and will be ignored!");
303 if(m_strIRIOrigin == L"*") //wildcard match means yes for subdomains
305 m_bSubDomainAccess = true;
308 ConfigParserData::AccessInfo accessInfo(m_strIRIOrigin,
310 //std::pair <ConfigParserData::AccessInfoSet::iterator, bool> ret =
311 m_data.accessInfoSet.insert(accessInfo);
314 virtual void Verify()
316 switch (m_standardType) {
317 case STANDARD_TYPE_WARP:
321 LogError("Error in Access tag - unknown standard.");
326 AccessParser(ConfigParserData& data) :
328 m_bSubDomainAccess(false),
329 m_standardType(STANDARD_TYPE_NONE),
334 ElementParserPtr Other()
336 return ElementParserPtr(new InnerElementsParser(
337 ElementParserPtr(shared_from_this())));
341 DPL::String m_strIRIOrigin;
342 bool m_bSubDomainAccess;
343 StandardType m_standardType;
345 ConfigParserData& m_data;
348 class DescriptionParser : public ElementParser
351 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
352 const DPL::String& /*name*/)
354 return DPL::MakeDelegate(this, &DescriptionParser::Other);
357 virtual void Accept(const Element& element)
359 m_lang = element.lang;
363 ElementParserPtr Other()
365 return ElementParserPtr(new InnerElementsParser(
366 std::static_pointer_cast<ElementParser>(
367 shared_from_this())));
370 virtual void Accept(const Text& text)
372 if (m_description.IsNull()) {
373 m_description = text.value;
375 *m_description += text.value;
379 virtual void Accept(const XmlAttribute& attribute)
381 if (attribute.name == L"dir") {
382 m_textDirection = Unicode::ParseDirAttribute(attribute);
386 virtual void Verify()
388 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
389 if (data.description.IsNull()) {
390 if (!m_description.IsNull()) {
391 Unicode::UpdateTextWithDirectionMark(m_textDirection,
394 data.description = m_description;
398 DescriptionParser(Unicode::Direction direction,
399 ConfigParserData& data) :
403 m_textDirection(direction)
407 ConfigParserData& m_data;
409 DPL::OptionalString m_description;
410 Unicode::Direction m_textDirection;
413 class AuthorParser : public ElementParser
416 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
417 const DPL::String& /*name*/)
419 return DPL::MakeDelegate(this, &AuthorParser::Other);
422 AuthorParser(Unicode::Direction direction,
423 ConfigParserData& data) :
425 m_textDirection(direction)
428 virtual void Accept(const Element& /*element*/)
433 virtual void Accept(const Text& text)
435 *(m_authorName) += text.value;
438 virtual void Accept(const XmlAttribute& attribute)
440 if (attribute.name == L"href") {
441 //Validate href IRI and ignore it if invalid
442 //See also test: ta-argMozRiC-an
443 LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
444 if (iri.Validate()) {
445 m_authorHref = attribute.value;
447 } else if (attribute.name == L"email") {
448 m_authorEmail = attribute.value;
449 } else if (attribute.name == L"dir") {
450 m_textDirection = Unicode::ParseDirAttribute(attribute);
454 virtual void Verify()
456 if (!m_data.authorName && !m_data.authorHref && !m_data.authorEmail) {
457 NormalizeString(m_authorName);
458 NormalizeString(m_authorHref);
459 NormalizeString(m_authorEmail);
460 if (!!m_authorName) {
461 Unicode::UpdateTextWithDirectionMark(m_textDirection,
463 m_data.authorName = m_authorName;
465 if (!!m_authorHref) {
466 m_data.authorHref = m_authorHref;
468 if (!!m_authorEmail) {
469 m_data.authorEmail = m_authorEmail;
474 ElementParserPtr Other()
476 return ElementParserPtr(new InnerElementsParser(
477 std::static_pointer_cast<ElementParser>(
478 shared_from_this())));
482 ConfigParserData& m_data;
483 DPL::OptionalString m_authorEmail;
484 DPL::OptionalString m_authorHref;
485 DPL::OptionalString m_authorName;
486 Unicode::Direction m_textDirection;
489 class LicenseParser : public ElementParser
492 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
493 const DPL::String& /*name*/)
495 return DPL::MakeDelegate(this, &LicenseParser::Other);
498 LicenseParser(Unicode::Direction direction,
499 ConfigParserData& data) :
502 m_textDirection(direction)
505 virtual void Accept(const Element& element)
507 if (m_license.IsNull()) {
508 m_lang = element.lang;
514 virtual void Accept(const Text& text)
517 *m_license += text.value;
521 virtual void Accept(const XmlAttribute& attribute)
524 if (attribute.name == L"href" && m_licenseHref.IsNull()) {
525 m_licenseHref = attribute.value;
526 } else if (attribute.name == L"file" && m_licenseFile.IsNull()) {
527 m_licenseFile = attribute.value;
528 } else if (attribute.name == L"dir") {
529 m_textDirection = Unicode::ParseDirAttribute(attribute);
534 virtual void Verify()
536 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
537 if (data.license.IsNull()) {
538 if (!m_license.IsNull()) {
539 Unicode::UpdateTextWithDirectionMark(m_textDirection,
542 data.license = m_license;
543 data.licenseHref = m_licenseHref;
544 data.licenseFile = m_licenseFile;
548 ElementParserPtr Other()
550 return ElementParserPtr(new InnerElementsParser(
551 ElementParserPtr(shared_from_this())));
555 ConfigParserData& m_data;
559 DPL::OptionalString m_license;
560 DPL::OptionalString m_licenseFile;
561 DPL::OptionalString m_licenseHref;
562 Unicode::Direction m_textDirection;
565 class IconParser : public ElementParser
567 DECLARE_EXCEPTION_TYPE(ElementParser::Exception::ParseError, BadSrcError)
570 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
571 const DPL::String& /*name*/)
573 return &IgnoringParser::Create; //ignore unknown according to w3c
576 IconParser(ConfigParserData& data) : ElementParser(),
580 virtual void Accept(const Element& /*element*/)
583 virtual void Accept(const XmlAttribute& attribute)
585 if (attribute.name == L"src") {
586 if (attribute.value.size() > 0) {
587 m_src = attribute.value;
589 } else if (attribute.name == L"width") {
590 m_width = ParseSizeAttributeValue(attribute.value);
591 } else if (attribute.name == L"height") {
592 m_height = ParseSizeAttributeValue(attribute.value);
596 virtual void Accept(const Text& /*text*/)
598 ThrowMsg(Exception::ParseError, "Icon element must be empty");
601 virtual void Verify()
603 if (m_src.IsNull()) {
604 LogWarning("src attribute of icon element is mandatory - ignoring");
610 ConfigParserData::Icon icon(delocalizeSrcPath(*m_src));
611 icon.width = m_width;
612 icon.height = m_height;
614 ConfigParserData::IconsList::iterator it = std::find(
615 m_data.iconsList.begin(), m_data.iconsList.end(), icon);
616 if (it == m_data.iconsList.end()) {
617 m_data.iconsList.push_front(icon);
622 LogWarning("src attribute is invalid: " << m_src);
627 ConfigParserData& m_data;
628 DPL::OptionalString m_src;
629 DPL::OptionalInt m_width;
630 DPL::OptionalInt m_height;
632 static DPL::OptionalInt ParseSizeAttributeValue(const DPL::String& value)
634 DPL::OptionalString normalizedValue = value;
635 NormalizeString(normalizedValue);
636 if (!(*normalizedValue).empty()) {
640 strtol(DPL::ToUTF8String(value).c_str(), &reterr, 10);
642 std::string(reterr) == DPL::ToUTF8String(value) ||
645 return DPL::OptionalInt::Null;
650 return DPL::OptionalInt::Null;
654 * @brief delocalizePath removes locales folder from relative path if
656 * @param source source string
658 * @throw BadSrcError if string is bad value of src attribute
660 * @return corrected string
662 static DPL::String delocalizeSrcPath(const DPL::String & source)
664 static const DPL::String localeFolder(L"locales/");
665 static const int index = localeFolder.size();
667 DPL::String result = source;
669 if (source.substr(0, index) == localeFolder) {
670 size_t pos = result.find_first_of('/', index);
671 if (pos != std::string::npos && pos + 1 < source.size()) {
672 result = result.substr(pos + 1, source.size());
681 class ContentParser : public ElementParser
684 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
685 const DPL::String& /*name*/)
687 return &IgnoringParser::Create; //ignore unknown according to w3c
690 ContentParser(ConfigParserData& data) :
695 virtual void Accept(const Element& element)
697 m_namespace = element.ns;
700 virtual void Accept(const Text& /*text*/)
703 virtual void Accept(const XmlAttribute& attribute)
705 DPL::String value = attribute.value;
706 NormalizeString(value);
708 if (attribute.name == L"src") {
710 } else if (attribute.name == L"type") {
712 MimeTypeUtils::MimeAttributes mimeAttributes =
713 MimeTypeUtils::getMimeAttributes(value);
714 if ((mimeAttributes.count(L"charset") > 0) && m_encoding.IsNull())
716 m_encoding = mimeAttributes[L"charset"];
718 } else if (attribute.name == L"encoding") {
719 if (!value.empty()) {
725 virtual void Verify()
727 if(!!m_data.startFileEncountered)
729 if(m_data.startFileNamespace == m_namespace
730 || m_namespace != ConfigurationNamespace::TizenWebAppNamespaceName)
734 //else continue -> if previous item was not in tizen namespace
737 m_data.startFileEncountered = true;
738 m_data.startFileNamespace = m_namespace;
740 //we're consciously setting startFile even if m_src is null or invalid.
741 //WidgetConfigurationManager will deal with this.
742 m_data.startFile = m_src;
745 m_data.startFileContentType = m_type;
747 m_data.startFileEncoding = m_encoding;
749 m_data.startFileEncoding = L"UTF-8";
755 DPL::OptionalString m_src;
756 DPL::OptionalString m_type;
757 DPL::OptionalString m_encoding;
758 ConfigParserData& m_data;
759 DPL::String m_namespace;
762 class PreferenceParser : public ElementParser
765 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
766 const DPL::String& /*name*/)
768 return &IgnoringParser::Create; //ignore unknown according to w3c
771 virtual void Accept(const XmlAttribute& attribute)
773 if (attribute.name == L"name") {
774 m_name = attribute.value;
775 } else if (attribute.name == L"value") {
776 m_value = attribute.value;
777 } else if (attribute.name == L"readonly") {
778 if (attribute.value == L"true") {
786 virtual void Accept(const Element& /*element*/)
789 virtual void Accept(const Text& /*text*/)
791 ThrowMsg(Exception::ParseError, "param element must be empty");
794 virtual void Verify()
796 if (m_name.IsNull()) {
797 LogWarning("preference element must have name attribute");
800 NormalizeString(m_name);
801 NormalizeString(m_value);
802 ConfigParserData::Preference preference(*m_name, m_required);
803 preference.value = m_value;
804 if (m_data.preferencesList.find(preference) ==
805 m_data.preferencesList.end())
807 m_data.preferencesList.insert(preference);
811 PreferenceParser(ConfigParserData& data) :
818 DPL::OptionalString m_name;
819 DPL::OptionalString m_value;
821 ConfigParserData& m_data;
824 class LinkParser : public ElementParser
827 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
828 const DPL::String& /*name*/)
830 return &DenyAllParser::Create;
833 virtual void Accept(const XmlAttribute& attribute)
835 if (m_properNamespace) {
836 LogDebug("attribute");
837 if (attribute.name == L"rel") {
838 if (attribute.value != L"describedby") {
839 ThrowMsg(Exception::ParseError,
840 "rel attribute must have describedby value");
842 } else if (attribute.name == L"type") {} else if (attribute.name ==
845 LogDebug("here is href");
846 m_href = attribute.value;
848 ThrowMsg(Exception::ParseError,
849 "unknown attribute '" +
850 DPL::ToUTF8String(attribute.name) +
851 "' in link element");
856 virtual void Accept(const Element& element)
859 ConfigurationNamespace::WacWidgetNamespaceNameForLinkElement)
861 m_properNamespace = true;
866 virtual void Accept(const Text&)
868 if (m_properNamespace) {
870 ThrowMsg(Exception::ParseError, "link element must be empty");
874 virtual void Verify()
877 ThrowMsg(Exception::ParseError,
878 "link element must have href attribute");
881 LibIri::Wrapper iri(DPL::ToUTF8String(*m_href).c_str());
882 if (!iri.Validate()) { // TODO: Better uri validator ?
883 ThrowMsg(Exception::ParseError,
884 "href attribute must be a valid iri/uri/url");
888 LinkParser(ConfigParserData& data) :
890 m_properNamespace(false),
892 m_href(DPL::OptionalString::Null)
896 bool m_properNamespace;
897 ConfigParserData& m_data;
898 DPL::OptionalString m_href;
901 class SettingParser : public ElementParser
904 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
905 const DPL::String& /*name*/)
907 return &IgnoringParser::Create; //ignore unknown according to w3c
910 virtual void Accept(const Text& /*text*/)
913 virtual void Accept(const Element& /*element*/)
916 virtual void Accept(const XmlAttribute& attribute)
918 m_setting.m_name = attribute.name;
919 m_setting.m_value = attribute.value;
920 m_data.settingsList.insert(m_setting);
923 virtual void Verify()
926 SettingParser(ConfigParserData& data) :
933 ConfigParserData& m_data;
934 ConfigParserData::Setting m_setting;
937 class AppControlParser : public ElementParser
940 struct SourceParser : public ElementParser
943 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
944 const DPL::String& /*name*/)
946 return &IgnoringParser::Create; //ignore unknown according to w3c
949 virtual void Accept(const Text& /*text*/)
952 virtual void Accept(const Element& /*element*/)
955 virtual void Accept(const XmlAttribute& attribute)
957 if (attribute.name == L"name") {
958 if (attribute.value.size() > 0) {
959 m_value = attribute.value;
960 NormalizeString(m_value);
965 virtual void Verify()
967 if (m_value.IsNull() || *m_value == L"") {
971 m_data.m_src = *m_value;
974 SourceParser(ConfigParserData::AppControlInfo& data) :
976 m_properNamespace(false),
981 bool m_properNamespace;
982 DPL::OptionalString m_value;
983 ConfigParserData::AppControlInfo& m_data;
986 struct OperationParser : public ElementParser
989 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
990 const DPL::String& /*name*/)
992 return &IgnoringParser::Create; //ignore unknown according to w3c
995 virtual void Accept(const Text& /*text*/)
998 virtual void Accept(const Element& /*element*/)
1001 virtual void Accept(const XmlAttribute& attribute)
1003 if (attribute.name == L"name") {
1004 if (attribute.value.size() > 0) {
1005 m_value = attribute.value;
1006 NormalizeString(m_value);
1011 virtual void Verify()
1013 if (m_value.IsNull() || *m_value == L"") {
1017 m_data.m_operation = *m_value;
1020 OperationParser(ConfigParserData::AppControlInfo& data) :
1022 m_properNamespace(false),
1027 bool m_properNamespace;
1028 DPL::OptionalString m_value;
1029 ConfigParserData::AppControlInfo& m_data;
1032 struct UriParser : public ElementParser
1035 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1036 const DPL::String& /*name*/)
1038 return &IgnoringParser::Create; //ignore unknown according to w3c
1041 virtual void Accept(const Text& /*text*/)
1044 virtual void Accept(const Element& /*element*/)
1047 virtual void Accept(const XmlAttribute& attribute)
1049 if (attribute.name == L"name") {
1050 if (attribute.value.size() > 0) {
1051 m_value = attribute.value;
1052 NormalizeString(m_value);
1057 virtual void Verify()
1060 DPL::String ignoreUri(L"file");
1062 if (!m_value.IsNull() && *m_value == ignoreUri)
1064 LogInfo("exception : '" << *m_value << "' scheme will be ignored.");
1065 m_value = DPL::OptionalString::Null;
1068 if (m_value.IsNull() || *m_value == L"") {
1072 DPL::String wildString(L"*/*");
1073 if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
1074 && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
1076 m_data.m_uriList.insert(*m_value);
1078 LogDebug("Ignoring uri with name" <<
1079 DPL::ToUTF8String(*m_value));
1083 UriParser(ConfigParserData::AppControlInfo& data) :
1085 m_properNamespace(false),
1090 bool m_properNamespace;
1091 DPL::OptionalString m_value;
1092 ConfigParserData::AppControlInfo& m_data;
1095 struct MimeParser : public ElementParser
1098 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1099 const DPL::String& /*name*/)
1101 return &IgnoringParser::Create; //ignore unknown according to w3c
1104 virtual void Accept(const Text& /*text*/)
1107 virtual void Accept(const Element& /*element*/)
1110 virtual void Accept(const XmlAttribute& attribute)
1112 if (attribute.name == L"name") {
1113 if (attribute.value.size() > 0) {
1114 m_value = attribute.value;
1115 NormalizeString(m_value);
1120 virtual void Verify()
1122 if (m_value.IsNull() || *m_value == L"") {
1126 DPL::String wildString(L"*/*");
1127 if ((m_data.m_mimeList.find(wildString) ==
1128 m_data.m_mimeList.end())
1129 && (m_data.m_mimeList.find(*m_value) ==
1130 m_data.m_mimeList.end()))
1132 m_data.m_mimeList.insert(*m_value);
1134 LogDebug("Ignoring mime with name" <<
1135 DPL::ToUTF8String(*m_value));
1139 MimeParser(ConfigParserData::AppControlInfo& data) :
1141 m_properNamespace(false),
1146 bool m_properNamespace;
1147 DPL::OptionalString m_value;
1148 ConfigParserData::AppControlInfo& m_data;
1151 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1152 const DPL::String& name)
1154 if (name == L"src") {
1155 return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1156 } else if (name == L"operation") {
1157 return DPL::MakeDelegate(this,
1158 &AppControlParser::OnOperationElement);
1159 } else if (name == L"uri") {
1160 return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1161 } else if (name == L"mime") {
1162 return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1164 return &IgnoringParser::Create; //ignore unknown according to w3c
1168 virtual void Accept(const XmlAttribute& /*attribute*/)
1171 virtual void Accept(const Element& element)
1173 LogWarning("namespace for app service = " << element.ns);
1174 if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1175 ThrowMsg(Exception::ParseError,
1176 "Wrong xml namespace for widget element");
1180 virtual void Accept(const Text& /*text*/)
1182 ThrowMsg(Exception::ParseError, "param element must be empty");
1185 virtual void Verify()
1187 if (m_appControl.m_src == L"") {
1188 ThrowMsg(Exception::ParseError, "service element must have src element");
1191 if (m_appControl.m_operation == L"") {
1192 ThrowMsg(Exception::ParseError, "service element must have operation element");
1195 m_data.appControlList.push_back(m_appControl);
1198 ElementParserPtr OnSourceElement()
1200 return ElementParserPtr(new SourceParser(m_appControl));
1203 ElementParserPtr OnOperationElement()
1205 return ElementParserPtr(new OperationParser(m_appControl));
1208 ElementParserPtr OnUriElement()
1210 return ElementParserPtr(new UriParser(m_appControl));
1213 ElementParserPtr OnMimeElement()
1215 return ElementParserPtr(new MimeParser(m_appControl));
1218 AppControlParser(ConfigParserData& data) :
1225 ConfigParserData& m_data;
1226 ConfigParserData::AppControlInfo m_appControl;
1229 class ApplicationParser : public ElementParser
1232 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1233 const DPL::String& /*name*/)
1235 return &IgnoringParser::Create; //ignore unknown according to w3c
1238 virtual void Accept(const Text& /*text*/)
1240 if (m_properNamespace) {
1241 ThrowMsg(Exception::ParseError, "application element must be empty");
1245 virtual void Accept(const Element& element)
1248 ConfigurationNamespace::TizenWebAppNamespaceName)
1250 m_properNamespace = true;
1254 virtual void Accept(const XmlAttribute& attribute)
1256 if (m_properNamespace) {
1257 if (attribute.name == L"id") {
1258 m_id = attribute.value;
1259 NormalizeAndTrimSpaceString(m_id);
1260 } else if (attribute.name == L"package") {
1261 m_package = attribute.value;
1262 } else if (attribute.name == L"required_version") {
1263 m_version = attribute.value;
1264 NormalizeString(m_version);
1266 ThrowMsg(Exception::ParseError,
1267 "unknown attribute '" +
1268 DPL::ToUTF8String(attribute.name) +
1269 "' in application element");
1274 virtual void Verify()
1276 VerifyIdAndPackage();
1280 ApplicationParser(ConfigParserData& data) :
1283 m_id(DPL::OptionalString::Null),
1284 m_version(DPL::OptionalString::Null),
1285 m_properNamespace(false)
1288 static const char* const REGEXP_ID;
1291 void VerifyIdAndPackage()
1295 ThrowMsg(Exception::ParseError,
1296 "application element must have package attribute");
1300 pcrecpp::RE re(REGEXP_PACKAGE);
1301 if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
1303 ThrowMsg(Exception::ParseError,
1304 "invalid format of package attribute");
1309 ThrowMsg(Exception::ParseError,
1310 "application element must have id attribute");
1314 std::string package;
1315 pcrecpp::RE re(REGEXP_ID);
1316 if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
1318 ThrowMsg(Exception::ParseError,
1319 "invalid format of id attribute");
1321 if (package != DPL::ToUTF8String(*m_package))
1323 ThrowMsg(Exception::ParseError,
1324 "invalid package prefix in id attribute");
1328 m_data.tizenAppId = m_id;
1329 m_data.tizenPkgId = m_package;
1332 void VerifyVersion()
1336 ThrowMsg(Exception::ParseError,
1337 "application element must have required_version attribute");
1341 pcrecpp::RE re(REGEXP_VERSION);
1342 if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
1344 ThrowMsg(Exception::ParseError,
1345 "invalid format of version attribute");
1349 m_data.tizenMinVersionRequired = m_version;
1352 static const char* const REGEXP_PACKAGE;
1353 static const char* const REGEXP_VERSION;
1355 ConfigParserData& m_data;
1356 DPL::OptionalString m_id;
1357 DPL::OptionalString m_package;
1358 DPL::OptionalString m_version;
1359 bool m_properNamespace;
1362 const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
1363 const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
1364 const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)?";
1366 class SplashParser : public ElementParser
1369 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1370 const DPL::String& /*name*/)
1372 return &IgnoringParser::Create; //ignore unknown according to w3c
1375 virtual void Accept(const XmlAttribute& attribute)
1377 if (m_properNamespace)
1379 if (attribute.name == L"src") {
1380 if (attribute.value.size() > 0) {
1381 m_src = attribute.value;
1387 virtual void Accept(const Element& element)
1390 ConfigurationNamespace::TizenWebAppNamespaceName)
1392 m_properNamespace = true;
1396 virtual void Accept(const Text& /*text*/)
1399 virtual void Verify()
1403 LogWarning("src attribute of splash element is mandatory - ignoring");
1407 m_data.splashImgSrc = m_src;
1410 SplashParser(ConfigParserData& data) :
1413 m_properNamespace(false)
1417 DPL::OptionalString m_src;
1418 ConfigParserData& m_data;
1419 bool m_properNamespace;
1422 class BackgroundParser : public ElementParser
1425 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1426 const DPL::String& /*name*/)
1428 return &IgnoringParser::Create; //ignore unknown according to w3c
1431 virtual void Accept(const XmlAttribute& attribute)
1433 if (attribute.name == L"src") {
1434 if (attribute.value.size() > 0) {
1435 m_src = attribute.value;
1440 virtual void Accept(const Element& /*element*/)
1443 virtual void Accept(const Text& /*text*/)
1446 virtual void Verify()
1448 if (m_src.IsNull()) {
1450 "src attribute of background element is mandatory - ignoring");
1454 m_data.backgroundPage = m_src;
1457 explicit BackgroundParser(ConfigParserData& data) :
1462 DPL::OptionalString m_src;
1463 ConfigParserData& m_data;
1466 class PrivilegeParser : public ElementParser
1469 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1470 const DPL::String& /*name*/)
1472 return &IgnoringParser::Create; //ignore unknown according to w3c
1475 virtual void Accept(const Text& /*text*/)
1478 virtual void Accept(const Element& element)
1481 ConfigurationNamespace::TizenWebAppNamespaceName)
1483 m_properNamespace = true;
1485 LogDebug("element");
1488 virtual void Accept(const XmlAttribute& attribute)
1490 if (m_properNamespace) {
1491 if (attribute.name == L"name") {
1492 m_feature.name = attribute.value;
1493 m_privilege.name = attribute.value;
1498 virtual void Verify()
1500 LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1502 if (m_feature.name != L"") {
1503 if (iri.Validate()) {
1504 if (m_data.featuresList.find(m_feature) ==
1505 m_data.featuresList.end())
1507 m_data.featuresList.insert(m_feature);
1509 LogDebug("Ignoring feature with name" <<
1510 DPL::ToUTF8String(m_feature.name));
1515 LibIri::Wrapper iriPrivilege(
1516 DPL::ToUTF8String(m_privilege.name).c_str());
1518 if (m_privilege.name != L"") {
1519 if (iriPrivilege.Validate()) {
1520 if (m_data.privilegeList.find(m_privilege) ==
1521 m_data.privilegeList.end())
1523 m_data.privilegeList.insert(m_privilege);
1525 LogDebug("Ignoring privilege with name" <<
1526 DPL::ToUTF8String(m_privilege.name));
1532 PrivilegeParser(ConfigParserData& data) :
1537 m_properNamespace(false)
1541 ConfigParserData& m_data;
1542 ConfigParserData::Feature m_feature;
1543 ConfigParserData::Privilege m_privilege;
1544 bool m_properNamespace;
1547 class CategoryParser : public ElementParser
1550 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1551 const DPL::String& /*name*/)
1553 return &IgnoringParser::Create; //ignore unknown according to w3c
1556 virtual void Accept(const XmlAttribute& attribute)
1558 if (attribute.name == L"name") {
1559 if (attribute.value.size() > 0) {
1560 m_name = attribute.value;
1565 virtual void Accept(const Element& /*element*/)
1568 virtual void Accept(const Text& /*text*/)
1571 virtual void Verify()
1573 if (m_name.IsNull()) {
1575 "name attribute of category element is mandatory - ignoring");
1579 if (m_data.categoryList.find(*m_name) ==
1580 m_data.categoryList.end())
1582 m_data.categoryList.insert(*m_name);
1586 explicit CategoryParser(ConfigParserData& data) :
1591 DPL::OptionalString m_name;
1592 ConfigParserData& m_data;
1595 class AppWidgetParser : public ElementParser
1599 struct BoxLabelParser : public ElementParser
1601 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1602 const DPL::String& /*name*/)
1604 return &IgnoringParser::Create; //ignore unknown according to w3c
1607 virtual void Accept(const XmlAttribute& attribute)
1609 if (m_properNamespace) {
1610 m_lang = attribute.lang;
1613 virtual void Accept(const Element& element)
1616 ConfigurationNamespace::TizenWebAppNamespaceName)
1618 m_properNamespace = true;
1622 virtual void Accept(const Text& text)
1624 if (m_properNamespace) {
1625 m_label = text.value;
1629 virtual void Verify()
1631 std::pair<DPL::String, DPL::String> boxLabel;
1632 if (m_label.empty()) {
1633 LogWarning("box-label element is empty");
1634 boxLabel.first = DPL::FromUTF8String("");
1635 boxLabel.second = DPL::FromUTF8String("");
1636 m_data.m_label.push_back(boxLabel);
1639 boxLabel.first = m_lang;
1640 boxLabel.second = m_label;
1641 m_data.m_label.push_back(boxLabel);
1645 BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1647 m_properNamespace(false),
1653 DPL::String m_label;
1654 bool m_properNamespace;
1655 ConfigParserData::LiveboxInfo& m_data;
1658 struct BoxIconParser : public ElementParser
1660 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1661 const DPL::String& /*name*/)
1663 return &IgnoringParser::Create; //ignore unknown according to w3c
1666 virtual void Accept(const XmlAttribute& attribute)
1668 if (m_properNamespace) {
1669 if (attribute.name == L"src") {
1670 m_icon = attribute.value;
1675 virtual void Accept(const Element& element)
1678 ConfigurationNamespace::TizenWebAppNamespaceName)
1680 m_properNamespace = true;
1684 virtual void Accept(const Text& /*text*/)
1687 virtual void Verify()
1689 if (m_icon.empty()) {
1690 ThrowMsg(Exception::ParseError,
1691 "src attribute of box-icon element is mandatory - ignoring");
1693 m_data.m_icon = m_icon;
1696 explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1698 m_properNamespace(false),
1704 bool m_properNamespace;
1705 ConfigParserData::LiveboxInfo& m_data;
1708 struct BoxContentParser : public ElementParser
1710 struct BoxSizeParser : public ElementParser
1712 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1713 const DPL::String& /*name*/)
1715 return &IgnoringParser::Create; //ignore unknown according to w3c
1718 virtual void Accept(const XmlAttribute& attribute)
1720 if (m_properNamespace) {
1721 if (attribute.name == L"preview") {
1722 m_preview = attribute.value;
1724 if (attribute.name == L"use-decoration") {
1725 m_useDecoration = attribute.value;
1730 virtual void Accept(const Element& element)
1733 ConfigurationNamespace::TizenWebAppNamespaceName)
1735 m_properNamespace = true;
1739 virtual void Accept(const Text& text)
1741 if (m_properNamespace) {
1742 m_size = text.value;
1746 virtual void Verify()
1748 if(m_size.empty()) {
1749 ThrowMsg(Exception::ParseError,
1750 "size is mandatory - ignoring");
1753 ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
1754 boxSizeInfo.m_size = m_size;
1755 boxSizeInfo.m_preview = m_preview;
1756 boxSizeInfo.m_useDecoration = m_useDecoration;
1757 m_data.m_boxSize.push_back(boxSizeInfo);
1760 explicit BoxSizeParser(
1761 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1763 m_properNamespace(false),
1769 DPL::String m_preview;
1770 DPL::String m_useDecoration;
1771 bool m_properNamespace;
1772 ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1775 struct PdParser : public ElementParser
1777 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1778 const DPL::String& /*name*/)
1780 return &IgnoringParser::Create; //ignore unknown according to w3c
1783 virtual void Accept(const XmlAttribute& attribute)
1785 if (m_properNamespace) {
1786 if (attribute.name == L"src") {
1787 m_src = attribute.value;
1788 } else if (attribute.name == L"width") {
1789 m_width = attribute.value;
1790 } else if (attribute.name == L"height") {
1791 m_height = attribute.value;
1792 } else if (attribute.name == L"fast-open") {
1793 m_fastOpen= attribute.value;
1798 virtual void Accept(const Element& element)
1801 ConfigurationNamespace::TizenWebAppNamespaceName)
1803 m_properNamespace = true;
1807 virtual void Accept(const Text& /*text*/)
1810 virtual void Verify()
1812 if (m_src.empty()) {
1813 ThrowMsg(Exception::ParseError,
1814 "src attribute of pd element is mandatory - ignoring");
1817 if (m_width.empty()) {
1818 ThrowMsg(Exception::ParseError,
1819 "width attribute of pd element is mandatory - ignoring");
1822 if (m_height.empty()) {
1823 ThrowMsg(Exception::ParseError,
1824 "height attribute of pd element is mandatory - ignoring");
1827 if (ConvertToInt(m_width).IsNull()) {
1828 ThrowMsg(Exception::ParseError,
1829 "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
1833 DPL::OptionalInt height = ConvertToInt(m_height);
1835 if (height.IsNull()) {
1836 ThrowMsg(Exception::ParseError,
1837 "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
1842 LogDebug("height attribute of pd element shouldn't be less than 1. Changed to 1 from " << *height);
1843 } else if (*height > 380){
1845 LogDebug("height attribute of pd element shouldn't be greater than 380. Changed to 380 from " << *height);
1848 m_data.m_pdSrc = m_src;
1849 m_data.m_pdWidth = m_width;
1850 m_data.m_pdHeight = m_height;
1851 m_data.m_pdFastOpen = m_fastOpen;
1855 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1857 m_properNamespace(false),
1862 DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
1865 std::string tempStr = DPL::ToUTF8String(intAsString);
1866 const char * intAsString_c = tempStr.c_str();
1868 long int intAsString_i = strtol(intAsString_c, &endptr, 10);
1870 if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
1871 || intAsString_i > INT_MAX || intAsString_i < INT_MIN
1872 || *endptr != '\0') {
1873 return DPL::OptionalInt::Null;
1876 return static_cast<int>(intAsString_i);
1880 DPL::String m_width;
1881 DPL::String m_height;
1882 DPL::String m_fastOpen;
1884 bool m_properNamespace;
1885 ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1888 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1889 const DPL::String& name)
1891 if (name == L"box-size") {
1892 return DPL::MakeDelegate(
1894 &AppWidgetParser::BoxContentParser::
1896 } else if (name == L"pd") {
1897 return DPL::MakeDelegate(
1899 &AppWidgetParser::BoxContentParser::
1902 ThrowMsg(Exception::ParseError,
1903 "No element parser for name: " << name);
1907 virtual void Accept(const XmlAttribute& attribute)
1909 if (m_properNamespace) {
1910 if (attribute.name == L"src") {
1911 m_box.m_boxSrc = attribute.value;
1913 if (attribute.name == L"mouse-event") {
1914 m_box.m_boxMouseEvent = attribute.value;
1916 if (attribute.name == L"touch-effect") {
1917 m_box.m_boxTouchEffect = attribute.value;
1922 virtual void Accept(const Element& element)
1925 ConfigurationNamespace::TizenWebAppNamespaceName)
1927 m_properNamespace = true;
1931 virtual void Accept(const Text& /*text*/)
1934 virtual void Verify()
1936 if (m_box.m_boxSrc.empty()) {
1937 ThrowMsg(Exception::ParseError,
1938 "src attribute of box-content element is mandatory - ignoring");
1941 if (!m_box.m_boxMouseEvent.empty() &&
1942 CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent))
1944 ThrowMsg(Exception::ParseError,
1945 "mouse-event attribute of box-content element should be true or false - ignoring");
1948 if (!m_box.m_boxTouchEffect.empty() &&
1949 CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect))
1951 ThrowMsg(Exception::ParseError,
1952 "touch-effect attribute of box-content element should be true or false - ignoring");
1955 if (m_box.m_boxMouseEvent.empty()) {
1956 m_box.m_boxMouseEvent = L"false";
1959 if (m_box.m_boxTouchEffect.empty()) {
1960 m_box.m_boxTouchEffect = L"true";
1963 if (m_box.m_boxSize.empty()) {
1964 ThrowMsg(Exception::ParseError,
1965 "box-size element of box-content element not found - ignoring");
1968 m_data.m_boxInfo = m_box;
1971 explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1973 m_properNamespace(false),
1977 ElementParserPtr OnBoxSizeElement()
1979 return ElementParserPtr(new BoxSizeParser(m_box));
1982 ElementParserPtr OnPdElement()
1984 return ElementParserPtr(new PdParser(m_box));
1988 bool m_properNamespace;
1989 ConfigParserData::LiveboxInfo& m_data;
1990 ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1993 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1994 const DPL::String& name)
1996 if (name == L"box-label") {
1997 return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
1998 } else if (name == L"box-icon") {
1999 return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
2000 } else if (name == L"box-content") {
2001 return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
2003 return &IgnoringParser::Create; //ignore unknown according to w3c
2007 virtual void Accept(const XmlAttribute& attribute)
2009 if (m_properNamespace) {
2010 if (attribute.name == L"id") {
2011 m_liveboxId = attribute.value;
2012 } else if (attribute.name == L"primary") {
2013 m_primary = attribute.value;
2014 } else if (attribute.name == L"auto-launch") {
2015 m_autoLaunch = attribute.value;
2016 } else if (attribute.name == L"update-period") {
2017 m_updatePeriod = attribute.value;
2018 } else if (attribute.name == L"type") {
2019 m_type = attribute.value;
2024 virtual void Accept(const Element& element)
2027 ConfigurationNamespace::TizenWebAppNamespaceName)
2029 m_properNamespace = true;
2033 virtual void Accept(const Text& /*text*/)
2036 virtual void Verify()
2038 if (m_liveboxId.empty()) {
2039 ThrowMsg(Exception::ParseError,
2040 "app-widget element must have id attribute");
2044 pcrecpp::RE re(REGEXP_ID_STRING.c_str());
2045 if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
2047 ThrowMsg(Exception::ParseError,
2048 "invalid format of app-widget id attribute");
2052 if (m_primary.empty())
2054 ThrowMsg(Exception::ParseError,
2055 "app-widget element must have primary attribute");
2056 } else if (CheckIfNotTrueNorFalse(m_primary))
2058 ThrowMsg(Exception::ParseError,
2059 "auto-launch attribute of app-widget element should be true or false - ignoring");
2062 if (!m_autoLaunch.empty() &&
2063 CheckIfNotTrueNorFalse(m_autoLaunch))
2065 ThrowMsg(Exception::ParseError,
2066 "auto-launch attribute of app-widget element should be true or false - ignoring");
2069 if (!m_updatePeriod.empty())
2073 std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
2075 //set standard locale to fix decimal point mark - '.'
2076 std::string currentLocale = setlocale(LC_NUMERIC, NULL);
2077 if (NULL == setlocale(LC_NUMERIC, "C"))
2078 LogWarning("Failed to change locale to \"C\"");
2079 double updatePeriod = strtod(tempStr.c_str(), &endptr);
2081 //go back to previous locale
2082 if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
2083 LogWarning("Failed to set previous locale");
2085 if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
2086 || *endptr != '\0') {
2087 ThrowMsg(Exception::ParseError,
2088 "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
2089 } else if (updatePeriod < 1800.0) {
2090 LogDebug("update-period attribute of app-widget element shouldn't be less than 1800.0 - changed to 1800 from value: " << m_updatePeriod);
2091 m_updatePeriod = L"1800.0";
2095 if (m_autoLaunch.empty()) {
2096 m_autoLaunch = L"false";
2099 if(m_livebox.m_label.empty()) {
2100 ThrowMsg(Exception::ParseError,
2101 "box-label element of app-widget element not found - ignoring");
2104 if(!m_boxContentFound) {
2105 ThrowMsg(Exception::ParseError,
2106 "box-content element of app-widget element not found - ignoring");
2109 m_livebox.m_liveboxId = m_liveboxId;
2110 m_livebox.m_primary = m_primary;
2111 m_livebox.m_autoLaunch = m_autoLaunch;
2112 m_livebox.m_updatePeriod = m_updatePeriod;
2113 m_livebox.m_type = m_type;
2115 m_data.m_livebox.push_back(m_livebox);
2118 explicit AppWidgetParser(ConfigParserData& data) :
2121 m_properNamespace(false),
2122 m_boxContentFound(false)
2124 m_livebox = ConfigParserData::LiveboxInfo();
2127 ElementParserPtr OnBoxLabelElement()
2130 return ElementParserPtr(new BoxLabelParser(m_livebox));
2133 ElementParserPtr OnBoxIconElement()
2135 return ElementParserPtr(new BoxIconParser(m_livebox));
2138 ElementParserPtr OnBoxContentElement()
2140 m_boxContentFound = true;
2141 return ElementParserPtr(new BoxContentParser(m_livebox));
2145 static std::string REGEXP_ID_STRING;
2146 ConfigParserData& m_data;
2147 ConfigParserData::LiveboxInfo m_livebox;
2148 DPL::String m_liveboxId;
2149 DPL::String m_primary;
2150 DPL::String m_autoLaunch;
2151 DPL::String m_updatePeriod;
2153 bool m_properNamespace;
2154 bool m_boxContentFound;
2156 static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
2158 return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
2162 std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
2164 class AllowNavigationParser : public ElementParser
2167 AllowNavigationParser(ConfigParserData& data) :
2170 m_properNamespace(false)
2173 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2174 const DPL::String& /*name*/)
2176 return &IgnoringParser::Create; //ignore unknown according to w3c
2179 virtual void Accept(const Element& element)
2181 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2182 m_properNamespace = true;
2186 virtual void Accept(const Text& text)
2188 if (m_properNamespace) {
2189 m_origin = text.value;
2193 virtual void Accept(const XmlAttribute& /*attribute*/)
2197 virtual void Verify()
2199 if (m_origin.IsNull()) {
2200 LogWarning("data is empty");
2204 char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
2205 char* ptr = strtok(data," ");
2206 while (ptr != NULL) {
2207 std::string origin = ptr;
2208 ptr = strtok(NULL," ");
2210 ConfigParserData::AllowNavigationInfo info(L"*", L"*");
2211 m_data.allowNavigationInfoList.push_back(info);
2215 DPL::ScopedPtr<iri_t> iri(iri_parse(origin.c_str()));
2216 if (!iri->host || strlen(iri->host) == 0) {
2217 // input origin should has schem and host
2218 // in case of file scheme path is filled
2220 LogWarning("input origin isn't verified");
2223 DPL::String scheme = L"*";
2224 if (iri->scheme && strlen(iri->scheme) != 0) {
2225 scheme = DPL::FromUTF8String(iri->scheme);
2227 ConfigParserData::AllowNavigationInfo info(
2229 DPL::FromUTF8String(iri->host));
2230 m_data.allowNavigationInfoList.push_back(info);
2236 DPL::OptionalString m_origin;
2237 ConfigParserData& m_data;
2238 bool m_properNamespace;
2241 class CspParser : public ElementParser
2244 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2245 const DPL::String& /*name*/)
2247 return &IgnoringParser::Create; //ignore unknown according to w3c
2250 CspParser(ConfigParserData& data) :
2253 m_properNamespace(false)
2256 virtual void Accept(const Element& element)
2258 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2259 m_properNamespace = true;
2263 virtual void Accept(const XmlAttribute& /*attribute*/)
2266 virtual void Accept(const Text& text)
2268 if (m_properNamespace) {
2269 m_policy = text.value;
2273 virtual void Verify()
2275 if (!m_policy.IsNull()) {
2276 m_data.cspPolicy = *m_policy;
2281 ConfigParserData& m_data;
2282 bool m_properNamespace;
2283 DPL::OptionalString m_policy;
2286 class CspReportOnlyParser : public ElementParser
2289 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2290 const DPL::String& /*name*/)
2292 return &IgnoringParser::Create; //ignore unknown according to w3c
2295 CspReportOnlyParser(ConfigParserData& data) :
2298 m_properNamespace(false)
2301 virtual void Accept(const Element& element)
2303 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2304 m_properNamespace = true;
2308 virtual void Accept(const XmlAttribute& /*attribute*/)
2311 virtual void Accept(const Text& text)
2313 if (m_properNamespace) {
2314 m_policy = text.value;
2318 virtual void Verify()
2320 if (!m_policy.IsNull()) {
2321 m_data.cspPolicyReportOnly = *m_policy;
2326 ConfigParserData& m_data;
2327 bool m_properNamespace;
2328 DPL::OptionalString m_policy;
2331 class AccountParser : public ElementParser
2334 struct AccountProviderParser : public ElementParser
2338 struct IconParser : public ElementParser
2341 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2342 const DPL::String& /*name*/)
2344 return &IgnoringParser::Create; //ignore unknown according to w3c
2347 virtual void Accept(const Text& text)
2349 if (text.value == L"") {
2352 m_value = text.value;
2355 virtual void Accept(const Element& /*element*/)
2358 virtual void Accept(const XmlAttribute& attribute)
2360 if (attribute.name == L"section") {
2361 if (attribute.value == L"account") {
2362 m_type = ConfigParserData::IconSectionType::DefaultIcon;
2363 } else if (attribute.value == L"account-small") {
2364 m_type = ConfigParserData::IconSectionType::SmallIcon;
2369 virtual void Verify()
2371 if (m_value.IsNull() || *m_value == L"") {
2375 std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2376 icon.first = m_type;
2377 icon.second = *m_value;
2379 m_data.m_iconSet.insert(icon);
2382 IconParser(ConfigParserData::AccountProvider& data) :
2384 m_properNamespace(false),
2385 m_type(ConfigParserData::DefaultIcon),
2390 bool m_properNamespace;
2391 ConfigParserData::IconSectionType m_type;
2392 ConfigParserData::AccountProvider& m_data;
2393 DPL::OptionalString m_value;
2396 struct DisplayNameParser : public ElementParser
2399 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2400 const DPL::String& /*name*/)
2402 return &IgnoringParser::Create; //ignore unknown according to w3c
2405 virtual void Accept(const Text& text)
2407 if (text.value == L"") {
2410 m_value = text.value;
2413 virtual void Accept(const Element& element)
2415 m_lang = element.lang;
2419 virtual void Accept(const XmlAttribute& /*attribute*/)
2422 virtual void Verify()
2424 if (m_value.IsNull() || *m_value == L"") {
2428 std::pair<DPL::String, DPL::String> name;
2429 name.first = *m_lang;
2430 name.second = *m_value;
2432 m_data.m_displayNameSet.insert(name);
2435 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2437 m_properNamespace(false),
2442 bool m_properNamespace;
2443 DPL::OptionalString m_lang;
2444 DPL::OptionalString m_value;
2445 ConfigParserData::AccountProvider& m_data;
2448 struct CapabilityParser : public ElementParser
2451 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2452 const DPL::String& /*name*/)
2454 return &IgnoringParser::Create; //ignore unknown according to w3c
2457 virtual void Accept(const Text& text)
2459 if (text.value == L"") {
2462 m_value = text.value;
2465 virtual void Accept(const Element& /*element*/)
2468 virtual void Accept(const XmlAttribute& /*attribute*/)
2471 virtual void Verify()
2473 if (m_value.IsNull() || *m_value == L"") {
2476 m_data.m_capabilityList.push_back(*m_value);
2479 CapabilityParser(ConfigParserData::AccountProvider& data) :
2481 m_properNamespace(false),
2486 bool m_properNamespace;
2487 DPL::OptionalString m_value;
2488 ConfigParserData::AccountProvider& m_data;
2490 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2491 const DPL::String& name)
2493 if (name == L"icon") {
2494 return DPL::MakeDelegate(this, &AccountProviderParser::OnIconElement);
2495 } else if (name == L"display-name") {
2496 return DPL::MakeDelegate(this,
2497 &AccountProviderParser::OnDisplayNameElement);
2498 } else if (name == L"capability") {
2499 return DPL::MakeDelegate(this, &AccountProviderParser::OnCapabilityElement);
2501 return &IgnoringParser::Create; //ignore unknown according to w3c
2505 virtual void Accept(const Text& /*text*/)
2508 virtual void Accept(const Element& /*element*/)
2511 virtual void Accept(const XmlAttribute& attribute)
2513 if (attribute.name == L"multiple-accounts-support") {
2514 if (attribute.value == L"true") {
2515 m_multiSupport = true;
2520 virtual void Verify()
2522 m_data.m_multiAccountSupport = m_multiSupport;
2525 ElementParserPtr OnIconElement()
2527 return ElementParserPtr(new IconParser(m_data));
2530 ElementParserPtr OnDisplayNameElement()
2532 return ElementParserPtr(new DisplayNameParser(m_data));
2535 ElementParserPtr OnCapabilityElement()
2537 return ElementParserPtr(new CapabilityParser(m_data));
2540 AccountProviderParser(ConfigParserData::AccountProvider& data) :
2542 m_properNamespace(false),
2543 m_multiSupport(false),
2548 bool m_properNamespace;
2549 bool m_multiSupport;
2550 ConfigParserData::AccountProvider& m_data;
2553 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2554 const DPL::String& name)
2556 if (name == L"account-provider") {
2557 return DPL::MakeDelegate(this, &AccountParser::OnProviderElement);
2559 return &IgnoringParser::Create; //ignore unknown according to w3c
2563 virtual void Accept(const Element& element)
2565 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2566 m_properNamespace = true;
2570 virtual void Accept(const XmlAttribute& /*attribute*/)
2573 virtual void Accept(const Text& /*text*/)
2576 virtual void Verify()
2579 ElementParserPtr OnProviderElement()
2581 return ElementParserPtr(new AccountProviderParser(m_account));
2584 AccountParser(ConfigParserData& data) :
2587 m_account(data.accountProvider),
2588 m_properNamespace(false),
2589 m_multiSupport(false)
2593 ConfigParserData& m_data;
2594 ConfigParserData::AccountProvider& m_account;
2595 bool m_properNamespace;
2596 bool m_multiSupport;
2599 class MetadataParser : public ElementParser
2602 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2603 const DPL::String& /*name*/)
2605 return &IgnoringParser::Create; //ignore unknown according to w3c
2608 virtual void Accept(const XmlAttribute& attribute)
2610 if (m_properNamespace) {
2611 if (attribute.name == L"key") {
2612 m_key = attribute.value;
2613 } else if (attribute.name == L"value") {
2614 m_value = attribute.value;
2619 virtual void Accept(const Element& element)
2621 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2622 m_properNamespace = true;
2626 virtual void Accept(const Text& /*text*/)
2628 ThrowMsg(Exception::ParseError, "param element must be empty");
2631 virtual void Verify()
2633 if (m_key.IsNull()) {
2634 LogWarning("metadata element must have key attribute");
2637 NormalizeString(m_key);
2638 NormalizeString(m_value);
2639 ConfigParserData::Metadata metaData(m_key, m_value);
2640 FOREACH(it, m_data.metadataList) {
2641 if (!DPL::StringCompare(*it->key, *m_key)) {
2642 LogError("Key isn't unique");
2646 m_data.metadataList.push_back(metaData);
2649 MetadataParser(ConfigParserData& data) :
2652 m_properNamespace(false)
2656 DPL::OptionalString m_key;
2657 DPL::OptionalString m_value;
2658 ConfigParserData& m_data;
2659 bool m_properNamespace;
2662 ElementParser::ActionFunc WidgetParser::GetElementParser(
2663 const DPL::String& /*ns*/,
2664 const DPL::String& name)
2666 FuncMap::const_iterator it = m_map.find(name);
2667 if (it != m_map.end()) {
2670 return &IgnoringParser::Create; //ignore unknown according to w3c
2674 WidgetParser::WidgetParser(ConfigParserData& data) :
2676 m_textDirection(Unicode::EMPTY)
2678 m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2679 m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2680 m_map[L"description"] =
2681 DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2682 m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2684 DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2685 m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2687 DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2688 m_map[L"preference"] =
2689 DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2690 m_map[L"link"] = DPL::MakeDelegate(this, &WidgetParser::OnLinkElement);
2692 DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2693 m_map[L"application"] = DPL::MakeDelegate(
2696 OnApplicationElement);
2697 m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2698 m_map[L"background"] = DPL::MakeDelegate(this,
2699 &WidgetParser::OnBackgroundElement);
2700 m_map[L"privilege"] = DPL::MakeDelegate(this,
2701 &WidgetParser::OnPrivilegeElement);
2702 m_map[L"app-control"] = DPL::MakeDelegate(
2705 OnAppControlElement);
2706 m_map[L"category"] = DPL::MakeDelegate(this,
2707 &WidgetParser::OnCategoryElement);
2708 m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
2710 m_map[L"content-security-policy"] = DPL::MakeDelegate(
2714 m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
2717 OnCspReportOnlyElement);
2719 #ifdef ALLOW_NAVIGATION_ENABLED
2720 m_map[L"allow-navigation"] =
2721 DPL::MakeDelegate(this, &WidgetParser::OnAllowNavigationElement);
2723 m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
2724 m_map[L"metadata"] = DPL::MakeDelegate(this, &WidgetParser::OnMetadataElement);
2727 ElementParserPtr WidgetParser::OnNameElement()
2729 return ElementParserPtr(new NameParser(m_textDirection, m_data));
2732 ElementParserPtr WidgetParser::OnAccessElement()
2734 return ElementParserPtr(new AccessParser(m_data));
2737 ElementParserPtr WidgetParser::OnDescriptionElement()
2739 return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2742 ElementParserPtr WidgetParser::OnAuthorElement()
2744 return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2747 ElementParserPtr WidgetParser::OnLicenseElement()
2749 return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2752 ElementParserPtr WidgetParser::OnIconElement()
2754 return ElementParserPtr(new IconParser(m_data));
2757 ElementParserPtr WidgetParser::OnContentElement()
2759 return ElementParserPtr(new ContentParser(m_data));
2762 ElementParserPtr WidgetParser::OnPreferenceElement()
2764 return ElementParserPtr(new PreferenceParser(m_data));
2767 ElementParserPtr WidgetParser::OnLinkElement()
2769 return ElementParserPtr(new LinkParser(m_data));
2772 ElementParserPtr WidgetParser::OnSettingElement()
2774 return ElementParserPtr(new SettingParser(m_data));
2777 ElementParserPtr WidgetParser::OnApplicationElement()
2779 return ElementParserPtr(new ApplicationParser(m_data));
2782 ElementParserPtr WidgetParser::OnSplashElement()
2784 return ElementParserPtr(new SplashParser(m_data));
2787 ElementParserPtr WidgetParser::OnBackgroundElement()
2789 return ElementParserPtr(new BackgroundParser(m_data));
2792 ElementParserPtr WidgetParser::OnPrivilegeElement()
2794 return ElementParserPtr(new PrivilegeParser(m_data));
2797 ElementParserPtr WidgetParser::OnAppControlElement()
2799 return ElementParserPtr(new AppControlParser(m_data));
2802 ElementParserPtr WidgetParser::OnCategoryElement()
2804 return ElementParserPtr(new CategoryParser(m_data));
2807 ElementParserPtr WidgetParser::OnAppWidgetElement()
2809 return ElementParserPtr(new AppWidgetParser(m_data));
2812 ElementParserPtr WidgetParser::OnCspElement()
2814 return ElementParserPtr(new CspParser(m_data));
2817 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
2819 return ElementParserPtr(new CspReportOnlyParser(m_data));
2822 ElementParserPtr WidgetParser::OnAllowNavigationElement()
2824 return ElementParserPtr(new AllowNavigationParser(m_data));
2827 ElementParserPtr WidgetParser::OnAccountElement()
2829 return ElementParserPtr(new AccountParser(m_data));
2832 ElementParserPtr WidgetParser::OnMetadataElement()
2834 return ElementParserPtr(new MetadataParser(m_data));
2837 void WidgetParser::Accept(const Element& element)
2839 if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2840 element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2842 ThrowMsg(Exception::ParseError,
2843 "Wrong xml namespace for widget element");
2847 void WidgetParser::Accept(const Text& /*text*/)
2849 ThrowMsg(Exception::ParseError, "widged element must be empty");
2852 void WidgetParser::Accept(const XmlAttribute& attribute)
2854 if (attribute.name == L"id") {
2855 LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2856 //If may important tests starts to fail this test we will have
2857 //to consider commenting this test out again.
2858 if (iri.Validate()) {
2859 m_data.widget_id = attribute.value;
2860 NormalizeString(m_data.widget_id);
2862 LogWarning("Widget id validation failed: " << attribute.value);
2864 } else if (attribute.name == L"version") {
2865 m_version = attribute.value;
2866 NormalizeString(m_version);
2867 } else if (attribute.name == L"min-version") {
2868 LogInfo("min-version attribute was found. Value: " << attribute.value);
2869 m_minVersion = attribute.value;
2870 NormalizeString(m_minVersion);
2871 m_data.minVersionRequired = m_minVersion;
2872 } else if (attribute.name == L"height") {
2873 DPL::OptionalString value = attribute.value;
2874 NormalizeString(value);
2875 std::string v = DPL::ToUTF8String(*value);
2878 unsigned char c = v.c_str()[0];
2881 for (size_t i = 0; i < v.size(); ++i) {
2890 m_data.height = val;
2893 } else if (attribute.name == L"width") {
2894 DPL::OptionalString value = attribute.value;
2895 NormalizeString(value);
2896 std::string v = DPL::ToUTF8String(*value);
2899 unsigned char c = v.c_str()[0];
2900 if (c >= '0' && c <= '9') {
2902 for (size_t i = 0; i < v.size(); ++i) {
2904 if (c >= '0' && c <= '9') {
2914 } else if (attribute.name == L"viewmodes") {
2915 DPL::Tokenize(attribute.value,
2917 std::inserter(m_windowModes,
2918 m_windowModes.end()),
2920 } else if (attribute.name == L"dir") {
2921 m_textDirection = Unicode::ParseDirAttribute(attribute);
2922 } else if (L"defaultlocale" == attribute.name) {
2923 if (!m_defaultlocale) {
2924 m_defaultlocale = attribute.value;
2925 NormalizeString(m_defaultlocale);
2926 if (!LanguageSubtagRstTreeSingleton::Instance().ValidateLanguageTag(
2927 DPL::ToUTF8String(*m_defaultlocale)))
2929 LogWarning("Language tag: " <<
2930 m_defaultlocale << " is not valid");
2931 m_defaultlocale = DPL::OptionalString::Null;
2933 LogDebug("Default Locale Found " << m_defaultlocale);
2936 LogWarning("Ignoring subsequent default locale");
2939 //Any other value consider as a namespace definition
2940 } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2941 LogInfo("Namespace domain: " << attribute.name);
2942 LogInfo("Namespace value: " << attribute.value);
2943 m_nameSpaces[attribute.name] = attribute.value;
2945 LogError("Unknown attirbute: namespace=" << attribute.ns <<
2946 ", name=" << attribute.name <<
2947 ", value=" << attribute.value);
2951 void WidgetParser::Verify()
2953 FOREACH(mode, m_windowModes) {
2954 if (L"windowed" == *mode || L"floating" == *mode ||
2955 L"fullscreen" == *mode || L"maximized" == *mode ||
2956 L"minimized" == *mode)
2958 m_data.windowModes.insert(*mode);
2961 if (!m_version.IsNull()) {
2962 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2963 m_data.version = m_version;
2965 m_data.defaultlocale = m_defaultlocale;
2966 FOREACH(ns, m_nameSpaces) {
2967 m_data.nameSpaces.insert(ns->second);