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>
35 #include "wrt-commons/i18n-dao-ro/i18n_dao_read_only.h"
38 #include <dpl/fast_delegate.h>
39 #include <dpl/foreach.h>
40 #include <dpl/scoped_ptr.h>
51 #include <installer_log.h>
53 using namespace WrtDB;
56 static const DPL::String UTF_LRE = L"\x0202a";
57 static const DPL::String UTF_LRO = L"\x0202d";
58 static const DPL::String UTF_RLE = L"\x0202b";
59 static const DPL::String UTF_RLO = L"\x0202e";
60 static const DPL::String UTF_PDF = L"\x0202c";
62 Direction ParseDirAttribute(const XmlAttribute& attribute)
64 Assert(L"dir" == attribute.name);
65 if (L"ltr" == attribute.value) {
67 } else if (L"rtl" == attribute.value) {
69 } else if (L"lro" == attribute.value) {
71 } else if (L"rlo" == attribute.value) {
74 _W("dir attribute has wrong value: %ls ", attribute.value.c_str());
79 void UpdateTextWithDirectionMark(Direction direction,
85 *text = UTF_RLO + *text + UTF_PDF;
88 *text = UTF_RLE + *text + UTF_PDF;
91 *text = UTF_LRE + *text + UTF_PDF;
94 *text = UTF_LRO + *text + UTF_PDF;
103 } // namespace Unicode
105 class InnerElementsParser : public ElementParser
108 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
109 const DPL::String& /*name*/)
111 return DPL::MakeDelegate(this, &InnerElementsParser::Other);
114 virtual void Accept(const Element& /*element*/)
117 virtual void Accept(const Text& text)
119 if (m_text.IsNull()) {
122 m_text->value += text.value;
126 virtual void Accept(const XmlAttribute& attribute)
128 if (attribute.name == L"dir") {
129 m_textDirection = Unicode::ParseDirAttribute(attribute);
133 virtual void Verify()
135 if (!m_text.IsNull()) {
136 Unicode::UpdateTextWithDirectionMark(m_textDirection,
138 m_parentParser->Accept(*m_text);
142 InnerElementsParser(ElementParserPtr parent) :
143 m_parentParser(parent),
144 m_textDirection(Unicode::EMPTY)
147 ElementParserPtr Other()
149 return ElementParserPtr(new InnerElementsParser(
150 std::static_pointer_cast<ElementParser>(
151 shared_from_this())));
155 DPL::Optional<Text> m_text;
156 ElementParserPtr m_parentParser;
157 Unicode::Direction m_textDirection;
160 class NameParser : public ElementParser
163 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
164 const DPL::String& /*name*/)
166 return DPL::MakeDelegate(this, &NameParser::Other);
169 virtual void Accept(const Element& element)
171 m_lang = element.lang;
175 virtual void Accept(const Text& text)
177 if (m_name.IsNull()) {
180 *m_name += text.value;
184 virtual void Accept(const XmlAttribute& attribute)
186 if (attribute.name == L"short") {
187 if (m_shortName.IsNull()) {
188 m_shortName = attribute.value;
190 } else if (attribute.name == L"dir") {
191 m_textDirection = Unicode::ParseDirAttribute(attribute);
195 virtual void Verify()
197 ConfigParserData::LocalizedData& data = m_data.localizedDataSet[m_lang];
198 if (data.name.IsNull()) {
199 NormalizeString(m_name);
200 NormalizeString(m_shortName);
201 if (!m_name.IsNull()) {
202 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_name);
205 if (!m_shortName.IsNull()) {
206 Unicode::UpdateTextWithDirectionMark(m_textDirection,
209 data.shortName = m_shortName;
213 NameParser(Unicode::Direction direction,
214 ConfigParserData& data) :
216 m_textDirection(direction)
219 ElementParserPtr Other()
221 return ElementParserPtr(new InnerElementsParser(
222 std::static_pointer_cast<ElementParser>(
223 shared_from_this())));
227 ConfigParserData& m_data;
228 DPL::OptionalString m_name;
229 DPL::OptionalString m_shortName;
230 DPL::OptionalString m_dir;
232 Unicode::Direction m_textDirection;
235 class AccessParser : public ElementParser
244 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
245 const DPL::String& /*name*/)
247 return DPL::MakeDelegate(this, &AccessParser::Other);
250 virtual void Accept(const Element& element)
252 // for tizen web apps WARP should be used
253 if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName ||
254 element.ns == ConfigurationNamespace::TizenWebAppNamespaceName)
256 m_standardType = STANDARD_TYPE_WARP;
260 virtual void Accept(const Text& /*text*/)
263 void AcceptWac(const XmlAttribute& attribute)
265 if (attribute.name == L"origin") {
266 m_strIRIOrigin = attribute.value;
267 NormalizeString(m_strIRIOrigin);
268 } else if (attribute.name == L"subdomains") {
269 DPL::String normalizedValue = attribute.value;
270 NormalizeString(normalizedValue);
272 if (normalizedValue == L"true") {
273 m_bSubDomainAccess = true;
274 } else if (normalizedValue == L"false") {
275 m_bSubDomainAccess = false;
280 virtual void Accept(const XmlAttribute& attribute)
282 switch (m_standardType) {
283 case STANDARD_TYPE_WARP:
284 AcceptWac(attribute);
287 _E("Error in Access tag - unknown standard.");
295 iri.set(m_strIRIOrigin, false);
297 if (!iri.isAccessDefinition()) {
298 _W("Access list element: %ls is not acceptable by WARP standard and will be ignored!",
299 m_strIRIOrigin.c_str());
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 _E("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 _W("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 _W("src attribute is invalid: %ls", (*m_src).c_str());
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 _W("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 SettingParser : public ElementParser
827 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
828 const DPL::String& /*name*/)
830 return &IgnoringParser::Create; //ignore unknown according to w3c
833 virtual void Accept(const Text& /*text*/)
836 virtual void Accept(const Element& /*element*/)
839 virtual void Accept(const XmlAttribute& attribute)
841 m_setting.m_name = attribute.name;
842 m_setting.m_value = attribute.value;
843 m_data.settingsList.insert(m_setting);
846 virtual void Verify()
849 SettingParser(ConfigParserData& data) :
856 ConfigParserData& m_data;
857 ConfigParserData::Setting m_setting;
860 class AppControlParser : public ElementParser
863 struct SourceParser : public ElementParser
866 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
867 const DPL::String& /*name*/)
869 return &IgnoringParser::Create; //ignore unknown according to w3c
872 virtual void Accept(const Text& /*text*/)
875 virtual void Accept(const Element& /*element*/)
878 virtual void Accept(const XmlAttribute& attribute)
880 if (attribute.name == L"name") {
881 if (attribute.value.size() > 0) {
882 m_value = attribute.value;
883 NormalizeString(m_value);
888 virtual void Verify()
890 if (m_value.IsNull() || *m_value == L"") {
894 m_data.m_src = *m_value;
897 SourceParser(ConfigParserData::AppControlInfo& data) :
899 m_properNamespace(false),
904 bool m_properNamespace;
905 DPL::OptionalString m_value;
906 ConfigParserData::AppControlInfo& m_data;
909 struct OperationParser : public ElementParser
912 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
913 const DPL::String& /*name*/)
915 return &IgnoringParser::Create; //ignore unknown according to w3c
918 virtual void Accept(const Text& /*text*/)
921 virtual void Accept(const Element& /*element*/)
924 virtual void Accept(const XmlAttribute& attribute)
926 if (attribute.name == L"name") {
927 if (attribute.value.size() > 0) {
928 m_value = attribute.value;
929 NormalizeString(m_value);
934 virtual void Verify()
936 if (m_value.IsNull() || *m_value == L"") {
940 m_data.m_operation = *m_value;
943 OperationParser(ConfigParserData::AppControlInfo& data) :
945 m_properNamespace(false),
950 bool m_properNamespace;
951 DPL::OptionalString m_value;
952 ConfigParserData::AppControlInfo& m_data;
955 struct UriParser : public ElementParser
958 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
959 const DPL::String& /*name*/)
961 return &IgnoringParser::Create; //ignore unknown according to w3c
964 virtual void Accept(const Text& /*text*/)
967 virtual void Accept(const Element& /*element*/)
970 virtual void Accept(const XmlAttribute& attribute)
972 if (attribute.name == L"name") {
973 if (attribute.value.size() > 0) {
974 m_value = attribute.value;
975 NormalizeString(m_value);
980 virtual void Verify()
983 DPL::String ignoreUri(L"file");
985 if (!m_value.IsNull() && *m_value == ignoreUri)
987 _D("exception : '%ls' scheme will be ignored.", (*m_value).c_str());
988 m_value = DPL::OptionalString::Null;
991 if (m_value.IsNull() || *m_value == L"") {
995 DPL::String wildString(L"*/*");
996 if ((m_data.m_uriList.find(wildString) == m_data.m_uriList.end())
997 && (m_data.m_uriList.find(*m_value) == m_data.m_uriList.end()))
999 m_data.m_uriList.insert(*m_value);
1001 _D("Ignoring uri with name %ls", (*m_value).c_str());
1005 UriParser(ConfigParserData::AppControlInfo& data) :
1007 m_properNamespace(false),
1012 bool m_properNamespace;
1013 DPL::OptionalString m_value;
1014 ConfigParserData::AppControlInfo& m_data;
1017 struct MimeParser : public ElementParser
1020 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1021 const DPL::String& /*name*/)
1023 return &IgnoringParser::Create; //ignore unknown according to w3c
1026 virtual void Accept(const Text& /*text*/)
1029 virtual void Accept(const Element& /*element*/)
1032 virtual void Accept(const XmlAttribute& attribute)
1034 if (attribute.name == L"name") {
1035 if (attribute.value.size() > 0) {
1036 m_value = attribute.value;
1037 NormalizeString(m_value);
1042 virtual void Verify()
1044 if (m_value.IsNull() || *m_value == L"") {
1048 DPL::String wildString(L"*/*");
1049 if ((m_data.m_mimeList.find(wildString) ==
1050 m_data.m_mimeList.end())
1051 && (m_data.m_mimeList.find(*m_value) ==
1052 m_data.m_mimeList.end()))
1054 m_data.m_mimeList.insert(*m_value);
1056 _D("Ignoring mime with name %ls", (*m_value).c_str());
1060 MimeParser(ConfigParserData::AppControlInfo& data) :
1062 m_properNamespace(false),
1067 bool m_properNamespace;
1068 DPL::OptionalString m_value;
1069 ConfigParserData::AppControlInfo& m_data;
1072 struct DispositionParser : public ElementParser
1075 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1076 const DPL::String& /*name*/)
1078 return &IgnoringParser::Create;
1081 virtual void Accept(const Text& /*text*/)
1084 virtual void Accept(const Element& /*element*/)
1087 virtual void Accept(const XmlAttribute& attribute)
1089 if (attribute.name == L"name") {
1090 if (attribute.value.size() > 0) {
1091 m_value = attribute.value;
1092 NormalizeString(m_value);
1097 virtual void Verify()
1099 if (m_value.IsNull() || *m_value == L"") {
1103 DPL::String windowString(L"window");
1104 DPL::String inlineString(L"inline");
1106 if (*m_value == L"window") {
1107 m_data.m_disposition =
1108 ConfigParserData::AppControlInfo::Disposition::WINDOW;
1109 } else if (*m_value == L"inline") {
1110 m_data.m_disposition =
1111 ConfigParserData::AppControlInfo::Disposition::INLINE;
1113 _D("Ignoring dispostion value %ls", (*m_value).c_str());
1117 DispositionParser(ConfigParserData::AppControlInfo& data) :
1119 m_properNamespace(false),
1124 bool m_properNamespace;
1125 DPL::OptionalString m_value;
1126 ConfigParserData::AppControlInfo& m_data;
1129 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1130 const DPL::String& name)
1132 if (name == L"src") {
1133 return DPL::MakeDelegate(this, &AppControlParser::OnSourceElement);
1134 } else if (name == L"operation") {
1135 return DPL::MakeDelegate(this,
1136 &AppControlParser::OnOperationElement);
1137 } else if (name == L"uri") {
1138 return DPL::MakeDelegate(this, &AppControlParser::OnUriElement);
1139 } else if (name == L"mime") {
1140 return DPL::MakeDelegate(this, &AppControlParser::OnMimeElement);
1141 } else if (name == L"disposition") {
1142 return DPL::MakeDelegate(this,
1143 &AppControlParser::OnDispositionElement);
1145 return &IgnoringParser::Create; //ignore unknown according to w3c
1149 virtual void Accept(const XmlAttribute& /*attribute*/)
1152 virtual void Accept(const Element& element)
1154 _W("namespace for app service = %ls", element.ns.c_str());
1155 if (element.ns == ConfigurationNamespace::W3CWidgetNamespaceName) {
1156 ThrowMsg(Exception::ParseError,
1157 "Wrong xml namespace for widget element");
1161 virtual void Accept(const Text& /*text*/)
1163 ThrowMsg(Exception::ParseError, "param element must be empty");
1166 virtual void Verify()
1168 if (m_appControl.m_src == L"") {
1169 ThrowMsg(Exception::ParseError, "service element must have src element");
1172 if (m_appControl.m_operation == L"") {
1173 ThrowMsg(Exception::ParseError, "service element must have operation element");
1176 m_data.appControlList.push_back(m_appControl);
1179 ElementParserPtr OnSourceElement()
1181 return ElementParserPtr(new SourceParser(m_appControl));
1184 ElementParserPtr OnOperationElement()
1186 return ElementParserPtr(new OperationParser(m_appControl));
1189 ElementParserPtr OnUriElement()
1191 return ElementParserPtr(new UriParser(m_appControl));
1194 ElementParserPtr OnMimeElement()
1196 return ElementParserPtr(new MimeParser(m_appControl));
1199 ElementParserPtr OnDispositionElement()
1201 return ElementParserPtr(new DispositionParser(m_appControl));
1204 AppControlParser(ConfigParserData& data) :
1211 ConfigParserData& m_data;
1212 ConfigParserData::AppControlInfo m_appControl;
1215 class ApplicationParser : public ElementParser
1218 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1219 const DPL::String& /*name*/)
1221 return &IgnoringParser::Create; //ignore unknown according to w3c
1224 virtual void Accept(const Text& /*text*/)
1226 if (m_properNamespace) {
1227 ThrowMsg(Exception::ParseError, "application element must be empty");
1231 virtual void Accept(const Element& element)
1234 ConfigurationNamespace::TizenWebAppNamespaceName)
1236 m_properNamespace = true;
1240 virtual void Accept(const XmlAttribute& attribute)
1242 if (m_properNamespace) {
1243 if (attribute.name == L"id") {
1244 m_id = attribute.value;
1245 NormalizeAndTrimSpaceString(m_id);
1246 } else if (attribute.name == L"package") {
1247 m_package = attribute.value;
1248 } else if (attribute.name == L"required_version") {
1249 m_version = attribute.value;
1250 NormalizeString(m_version);
1252 ThrowMsg(Exception::ParseError,
1253 "unknown attribute '" +
1254 DPL::ToUTF8String(attribute.name) +
1255 "' in application element");
1260 virtual void Verify()
1262 VerifyIdAndPackage();
1266 ApplicationParser(ConfigParserData& data) :
1269 m_id(DPL::OptionalString::Null),
1270 m_version(DPL::OptionalString::Null),
1271 m_properNamespace(false)
1274 static const char* const REGEXP_ID;
1277 void VerifyIdAndPackage()
1281 ThrowMsg(Exception::ParseError,
1282 "application element must have package attribute");
1286 pcrecpp::RE re(REGEXP_PACKAGE);
1287 if (!re.FullMatch(DPL::ToUTF8String(*m_package)))
1289 ThrowMsg(Exception::ParseError,
1290 "invalid format of package attribute");
1295 ThrowMsg(Exception::ParseError,
1296 "application element must have id attribute");
1300 std::string package;
1301 pcrecpp::RE re(REGEXP_ID);
1302 if (!re.FullMatch(DPL::ToUTF8String(*m_id), &package))
1304 ThrowMsg(Exception::ParseError,
1305 "invalid format of id attribute");
1307 if (package != DPL::ToUTF8String(*m_package))
1309 ThrowMsg(Exception::ParseError,
1310 "invalid package prefix in id attribute");
1314 m_data.tizenAppId = m_id;
1315 m_data.tizenPkgId = m_package;
1318 void VerifyVersion()
1322 ThrowMsg(Exception::ParseError,
1323 "application element must have required_version attribute");
1327 pcrecpp::RE re(REGEXP_VERSION);
1328 if (!re.FullMatch(DPL::ToUTF8String(*m_version)))
1330 ThrowMsg(Exception::ParseError,
1331 "invalid format of version attribute");
1335 m_data.tizenMinVersionRequired = m_version;
1338 static const char* const REGEXP_PACKAGE;
1339 static const char* const REGEXP_VERSION;
1341 ConfigParserData& m_data;
1342 DPL::OptionalString m_id;
1343 DPL::OptionalString m_package;
1344 DPL::OptionalString m_version;
1345 bool m_properNamespace;
1348 const char* const ApplicationParser::REGEXP_PACKAGE = "[0-9A-Za-z]{10}";
1349 const char* const ApplicationParser::REGEXP_ID = "([0-9A-Za-z]{10})\\.[0-9A-Za-z]{1,52}";
1350 const char* const ApplicationParser::REGEXP_VERSION = "\\d+\\.\\d+(\\.\\d+)?";
1352 class SplashParser : public ElementParser
1355 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1356 const DPL::String& /*name*/)
1358 return &IgnoringParser::Create; //ignore unknown according to w3c
1361 virtual void Accept(const XmlAttribute& attribute)
1363 if (m_properNamespace)
1365 if (attribute.name == L"src") {
1366 if (attribute.value.size() > 0) {
1367 m_src = attribute.value;
1373 virtual void Accept(const Element& element)
1376 ConfigurationNamespace::TizenWebAppNamespaceName)
1378 m_properNamespace = true;
1382 virtual void Accept(const Text& /*text*/)
1385 virtual void Verify()
1389 _W("src attribute of splash element is mandatory - ignoring");
1393 m_data.splashImgSrc = m_src;
1396 SplashParser(ConfigParserData& data) :
1399 m_properNamespace(false)
1403 DPL::OptionalString m_src;
1404 ConfigParserData& m_data;
1405 bool m_properNamespace;
1408 class BackgroundParser : public ElementParser
1411 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1412 const DPL::String& /*name*/)
1414 return &IgnoringParser::Create; //ignore unknown according to w3c
1417 virtual void Accept(const XmlAttribute& attribute)
1419 if (attribute.name == L"src") {
1420 if (attribute.value.size() > 0) {
1421 m_src = attribute.value;
1426 virtual void Accept(const Element& /*element*/)
1429 virtual void Accept(const Text& /*text*/)
1432 virtual void Verify()
1434 if (m_src.IsNull()) {
1435 _W("src attribute of background element is mandatory - ignoring");
1439 m_data.backgroundPage = m_src;
1442 explicit BackgroundParser(ConfigParserData& data) :
1447 DPL::OptionalString m_src;
1448 ConfigParserData& m_data;
1451 class PrivilegeParser : public ElementParser
1454 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1455 const DPL::String& /*name*/)
1457 return &IgnoringParser::Create; //ignore unknown according to w3c
1460 virtual void Accept(const Text& /*text*/)
1463 virtual void Accept(const Element& element)
1466 ConfigurationNamespace::TizenWebAppNamespaceName)
1468 m_properNamespace = true;
1473 virtual void Accept(const XmlAttribute& attribute)
1475 if (m_properNamespace) {
1476 if (attribute.name == L"name") {
1477 m_feature.name = attribute.value;
1478 m_privilege.name = attribute.value;
1483 virtual void Verify()
1485 LibIri::Wrapper iri(DPL::ToUTF8String(m_feature.name).c_str());
1487 if (m_feature.name != L"") {
1488 if (iri.Validate()) {
1489 if (m_data.featuresList.find(m_feature) ==
1490 m_data.featuresList.end())
1492 m_data.featuresList.insert(m_feature);
1494 _D("Ignoring feature with name %ls", m_feature.name.c_str());
1499 LibIri::Wrapper iriPrivilege(
1500 DPL::ToUTF8String(m_privilege.name).c_str());
1502 if (m_privilege.name != L"") {
1503 if (iriPrivilege.Validate()) {
1504 if (m_data.privilegeList.find(m_privilege) ==
1505 m_data.privilegeList.end())
1507 m_data.privilegeList.insert(m_privilege);
1509 _D("Ignoring privilege with name %ls", m_privilege.name.c_str());
1515 PrivilegeParser(ConfigParserData& data) :
1520 m_properNamespace(false)
1524 ConfigParserData& m_data;
1525 ConfigParserData::Feature m_feature;
1526 ConfigParserData::Privilege m_privilege;
1527 bool m_properNamespace;
1530 class CategoryParser : public ElementParser
1533 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1534 const DPL::String& /*name*/)
1536 return &IgnoringParser::Create; //ignore unknown according to w3c
1539 virtual void Accept(const XmlAttribute& attribute)
1541 if (attribute.name == L"name") {
1542 if (attribute.value.size() > 0) {
1543 m_name = attribute.value;
1548 virtual void Accept(const Element& /*element*/)
1551 virtual void Accept(const Text& /*text*/)
1554 virtual void Verify()
1556 if (m_name.IsNull()) {
1557 _W("name attribute of category element is mandatory - ignoring");
1561 if (m_data.categoryList.find(*m_name) ==
1562 m_data.categoryList.end())
1564 m_data.categoryList.insert(*m_name);
1568 explicit CategoryParser(ConfigParserData& data) :
1573 DPL::OptionalString m_name;
1574 ConfigParserData& m_data;
1577 class AppWidgetParser : public ElementParser
1581 struct BoxLabelParser : public ElementParser
1583 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1584 const DPL::String& /*name*/)
1586 return &IgnoringParser::Create; //ignore unknown according to w3c
1589 virtual void Accept(const XmlAttribute& attribute)
1591 if (m_properNamespace) {
1592 m_lang = attribute.lang;
1595 virtual void Accept(const Element& element)
1598 ConfigurationNamespace::TizenWebAppNamespaceName)
1600 m_properNamespace = true;
1604 virtual void Accept(const Text& text)
1606 if (m_properNamespace) {
1607 m_label = text.value;
1611 virtual void Verify()
1613 std::pair<DPL::String, DPL::String> boxLabel;
1614 if (m_label.empty()) {
1615 _W("box-label element is empty");
1616 boxLabel.first = DPL::FromUTF8String("");
1617 boxLabel.second = DPL::FromUTF8String("");
1618 m_data.m_label.push_back(boxLabel);
1621 boxLabel.first = m_lang;
1622 boxLabel.second = m_label;
1623 m_data.m_label.push_back(boxLabel);
1627 BoxLabelParser(ConfigParserData::LiveboxInfo& data) :
1629 m_properNamespace(false),
1635 DPL::String m_label;
1636 bool m_properNamespace;
1637 ConfigParserData::LiveboxInfo& m_data;
1640 struct BoxIconParser : public ElementParser
1642 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1643 const DPL::String& /*name*/)
1645 return &IgnoringParser::Create; //ignore unknown according to w3c
1648 virtual void Accept(const XmlAttribute& attribute)
1650 if (m_properNamespace) {
1651 if (attribute.name == L"src") {
1652 m_icon = attribute.value;
1657 virtual void Accept(const Element& element)
1660 ConfigurationNamespace::TizenWebAppNamespaceName)
1662 m_properNamespace = true;
1666 virtual void Accept(const Text& /*text*/)
1669 virtual void Verify()
1671 if (m_icon.empty()) {
1672 ThrowMsg(Exception::ParseError,
1673 "src attribute of box-icon element is mandatory - ignoring");
1675 m_data.m_icon = m_icon;
1678 explicit BoxIconParser(ConfigParserData::LiveboxInfo& data) :
1680 m_properNamespace(false),
1686 bool m_properNamespace;
1687 ConfigParserData::LiveboxInfo& m_data;
1690 struct BoxContentParser : public ElementParser
1692 struct BoxSizeParser : public ElementParser
1694 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1695 const DPL::String& /*name*/)
1697 return &IgnoringParser::Create; //ignore unknown according to w3c
1700 virtual void Accept(const XmlAttribute& attribute)
1702 if (m_properNamespace) {
1703 if (attribute.name == L"preview") {
1704 m_preview = attribute.value;
1706 if (attribute.name == L"use-decoration") {
1707 m_useDecoration = attribute.value;
1712 virtual void Accept(const Element& element)
1715 ConfigurationNamespace::TizenWebAppNamespaceName)
1717 m_properNamespace = true;
1721 virtual void Accept(const Text& text)
1723 if (m_properNamespace) {
1724 m_size = text.value;
1728 virtual void Verify()
1730 if(m_size.empty()) {
1731 ThrowMsg(Exception::ParseError,
1732 "size is mandatory - ignoring");
1735 ConfigParserData::LiveboxInfo::BoxSizeInfo boxSizeInfo;
1736 boxSizeInfo.m_size = m_size;
1737 boxSizeInfo.m_preview = m_preview;
1738 boxSizeInfo.m_useDecoration = m_useDecoration;
1739 m_data.m_boxSize.push_back(boxSizeInfo);
1742 explicit BoxSizeParser(
1743 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1745 m_properNamespace(false),
1751 DPL::String m_preview;
1752 DPL::String m_useDecoration;
1753 bool m_properNamespace;
1754 ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1757 struct PdParser : public ElementParser
1759 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1760 const DPL::String& /*name*/)
1762 return &IgnoringParser::Create; //ignore unknown according to w3c
1765 virtual void Accept(const XmlAttribute& attribute)
1767 if (m_properNamespace) {
1768 if (attribute.name == L"src") {
1769 m_src = attribute.value;
1770 } else if (attribute.name == L"width") {
1771 m_width = attribute.value;
1772 } else if (attribute.name == L"height") {
1773 m_height = attribute.value;
1774 } else if (attribute.name == L"fast-open") {
1775 m_fastOpen= attribute.value;
1780 virtual void Accept(const Element& element)
1783 ConfigurationNamespace::TizenWebAppNamespaceName)
1785 m_properNamespace = true;
1789 virtual void Accept(const Text& /*text*/)
1792 virtual void Verify()
1794 if (m_src.empty()) {
1795 ThrowMsg(Exception::ParseError,
1796 "src attribute of pd element is mandatory - ignoring");
1799 if (m_width.empty()) {
1800 ThrowMsg(Exception::ParseError,
1801 "width attribute of pd element is mandatory - ignoring");
1804 if (m_height.empty()) {
1805 ThrowMsg(Exception::ParseError,
1806 "height attribute of pd element is mandatory - ignoring");
1809 if (ConvertToInt(m_width).IsNull()) {
1810 ThrowMsg(Exception::ParseError,
1811 "width attribute of pd element cannot be converted to int - ignoring. value: " << m_width);
1815 DPL::OptionalInt height = ConvertToInt(m_height);
1817 if (height.IsNull()) {
1818 ThrowMsg(Exception::ParseError,
1819 "height attribute of pd element cannot be converted to int - ignoring. value: " << m_height);
1824 _D("height attribute of pd element shouldn't be less than 1. Changed to 1 from %d", *height);
1825 } else if (*height > 380){
1827 _D("height attribute of pd element shouldn't be greater than 380. Changed to 380 from %d", *height);
1830 m_data.m_pdSrc = m_src;
1831 m_data.m_pdWidth = m_width;
1832 m_data.m_pdHeight = m_height;
1833 m_data.m_pdFastOpen = m_fastOpen;
1837 ConfigParserData::LiveboxInfo::BoxContentInfo& data) :
1839 m_properNamespace(false),
1844 DPL::OptionalInt ConvertToInt(const DPL::String& intAsString)
1847 std::string tempStr = DPL::ToUTF8String(intAsString);
1848 const char * intAsString_c = tempStr.c_str();
1850 long int intAsString_i = strtol(intAsString_c, &endptr, 10);
1852 if ((errno == ERANGE && (intAsString_i == LONG_MAX || intAsString_i == LONG_MIN))
1853 || intAsString_i > INT_MAX || intAsString_i < INT_MIN
1854 || *endptr != '\0') {
1855 return DPL::OptionalInt::Null;
1858 return static_cast<int>(intAsString_i);
1862 DPL::String m_width;
1863 DPL::String m_height;
1864 DPL::String m_fastOpen;
1866 bool m_properNamespace;
1867 ConfigParserData::LiveboxInfo::BoxContentInfo& m_data;
1870 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1871 const DPL::String& name)
1873 if (name == L"box-size") {
1874 return DPL::MakeDelegate(
1876 &AppWidgetParser::BoxContentParser::
1878 } else if (name == L"pd") {
1879 return DPL::MakeDelegate(
1881 &AppWidgetParser::BoxContentParser::
1884 ThrowMsg(Exception::ParseError,
1885 "No element parser for name: " << name);
1889 virtual void Accept(const XmlAttribute& attribute)
1891 if (m_properNamespace) {
1892 if (attribute.name == L"src") {
1893 m_box.m_boxSrc = attribute.value;
1895 if (attribute.name == L"mouse-event") {
1896 m_box.m_boxMouseEvent = attribute.value;
1898 if (attribute.name == L"touch-effect") {
1899 m_box.m_boxTouchEffect = attribute.value;
1904 virtual void Accept(const Element& element)
1907 ConfigurationNamespace::TizenWebAppNamespaceName)
1909 m_properNamespace = true;
1913 virtual void Accept(const Text& /*text*/)
1916 virtual void Verify()
1918 if (m_box.m_boxSrc.empty()) {
1919 ThrowMsg(Exception::ParseError,
1920 "src attribute of box-content element is mandatory - ignoring");
1923 if (!m_box.m_boxMouseEvent.empty() &&
1924 CheckIfNotTrueNorFalse(m_box.m_boxMouseEvent))
1926 ThrowMsg(Exception::ParseError,
1927 "mouse-event attribute of box-content element should be true or false - ignoring");
1930 if (!m_box.m_boxTouchEffect.empty() &&
1931 CheckIfNotTrueNorFalse(m_box.m_boxTouchEffect))
1933 ThrowMsg(Exception::ParseError,
1934 "touch-effect attribute of box-content element should be true or false - ignoring");
1937 if (m_box.m_boxMouseEvent.empty()) {
1938 m_box.m_boxMouseEvent = L"false";
1941 if (m_box.m_boxTouchEffect.empty()) {
1942 m_box.m_boxTouchEffect = L"true";
1945 if (m_box.m_boxSize.empty()) {
1946 ThrowMsg(Exception::ParseError,
1947 "box-size element of box-content element not found - ignoring");
1950 m_data.m_boxInfo = m_box;
1953 explicit BoxContentParser(ConfigParserData::LiveboxInfo& data) :
1955 m_properNamespace(false),
1959 ElementParserPtr OnBoxSizeElement()
1961 return ElementParserPtr(new BoxSizeParser(m_box));
1964 ElementParserPtr OnPdElement()
1966 return ElementParserPtr(new PdParser(m_box));
1970 bool m_properNamespace;
1971 ConfigParserData::LiveboxInfo& m_data;
1972 ConfigParserData::LiveboxInfo::BoxContentInfo m_box;
1975 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
1976 const DPL::String& name)
1978 if (name == L"box-label") {
1979 return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxLabelElement);
1980 } else if (name == L"box-icon") {
1981 return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxIconElement);
1982 } else if (name == L"box-content") {
1983 return DPL::MakeDelegate(this, &AppWidgetParser::OnBoxContentElement);
1985 return &IgnoringParser::Create; //ignore unknown according to w3c
1989 virtual void Accept(const XmlAttribute& attribute)
1991 if (m_properNamespace) {
1992 if (attribute.name == L"id") {
1993 m_liveboxId = attribute.value;
1994 } else if (attribute.name == L"primary") {
1995 m_primary = attribute.value;
1996 } else if (attribute.name == L"auto-launch") {
1997 m_autoLaunch = attribute.value;
1998 } else if (attribute.name == L"update-period") {
1999 m_updatePeriod = attribute.value;
2000 } else if (attribute.name == L"type") {
2001 m_type = attribute.value;
2006 virtual void Accept(const Element& element)
2009 ConfigurationNamespace::TizenWebAppNamespaceName)
2011 m_properNamespace = true;
2015 virtual void Accept(const Text& /*text*/)
2018 virtual void Verify()
2020 if (m_liveboxId.empty()) {
2021 ThrowMsg(Exception::ParseError,
2022 "app-widget element must have id attribute");
2026 pcrecpp::RE re(REGEXP_ID_STRING.c_str());
2027 if (!re.FullMatch(DPL::ToUTF8String(m_liveboxId)))
2029 ThrowMsg(Exception::ParseError,
2030 "invalid format of app-widget id attribute");
2034 if (m_primary.empty())
2036 ThrowMsg(Exception::ParseError,
2037 "app-widget element must have primary attribute");
2038 } else if (CheckIfNotTrueNorFalse(m_primary))
2040 ThrowMsg(Exception::ParseError,
2041 "auto-launch attribute of app-widget element should be true or false - ignoring");
2044 if (!m_autoLaunch.empty() &&
2045 CheckIfNotTrueNorFalse(m_autoLaunch))
2047 ThrowMsg(Exception::ParseError,
2048 "auto-launch attribute of app-widget element should be true or false - ignoring");
2051 if (!m_updatePeriod.empty())
2055 std::string tempStr = DPL::ToUTF8String(m_updatePeriod);
2057 //set standard locale to fix decimal point mark - '.'
2058 std::string currentLocale = setlocale(LC_NUMERIC, NULL);
2059 if (NULL == setlocale(LC_NUMERIC, "C"))
2060 _W("Failed to change locale to \"C\"");
2061 double updatePeriod = strtod(tempStr.c_str(), &endptr);
2063 //go back to previous locale
2064 if (NULL == setlocale(LC_NUMERIC, currentLocale.c_str()))
2065 _W("Failed to set previous locale");
2067 if ((errno == ERANGE && (updatePeriod == -HUGE_VAL || updatePeriod == HUGE_VAL))
2068 || *endptr != '\0') {
2069 ThrowMsg(Exception::ParseError,
2070 "update-period attribute of app-widget element should be a number - ignoring. current value: " << m_updatePeriod);
2071 } else if (updatePeriod < 1800.0) {
2072 _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());
2073 m_updatePeriod = L"1800.0";
2077 if (m_autoLaunch.empty()) {
2078 m_autoLaunch = L"false";
2081 if(m_livebox.m_label.empty()) {
2082 ThrowMsg(Exception::ParseError,
2083 "box-label element of app-widget element not found - ignoring");
2086 if(!m_boxContentFound) {
2087 ThrowMsg(Exception::ParseError,
2088 "box-content element of app-widget element not found - ignoring");
2091 m_livebox.m_liveboxId = m_liveboxId;
2092 m_livebox.m_primary = m_primary;
2093 m_livebox.m_autoLaunch = m_autoLaunch;
2094 m_livebox.m_updatePeriod = m_updatePeriod;
2095 m_livebox.m_type = m_type;
2097 m_data.m_livebox.push_back(m_livebox);
2100 explicit AppWidgetParser(ConfigParserData& data) :
2103 m_properNamespace(false),
2104 m_boxContentFound(false)
2106 m_livebox = ConfigParserData::LiveboxInfo();
2109 ElementParserPtr OnBoxLabelElement()
2112 return ElementParserPtr(new BoxLabelParser(m_livebox));
2115 ElementParserPtr OnBoxIconElement()
2117 return ElementParserPtr(new BoxIconParser(m_livebox));
2120 ElementParserPtr OnBoxContentElement()
2122 m_boxContentFound = true;
2123 return ElementParserPtr(new BoxContentParser(m_livebox));
2127 static std::string REGEXP_ID_STRING;
2128 ConfigParserData& m_data;
2129 ConfigParserData::LiveboxInfo m_livebox;
2130 DPL::String m_liveboxId;
2131 DPL::String m_primary;
2132 DPL::String m_autoLaunch;
2133 DPL::String m_updatePeriod;
2135 bool m_properNamespace;
2136 bool m_boxContentFound;
2138 static bool CheckIfNotTrueNorFalse(const DPL::String &stringToCheck)
2140 return stringToCheck.compare(L"true") != 0 && stringToCheck.compare(L"false") != 0;
2144 std::string AppWidgetParser::REGEXP_ID_STRING = std::string(ApplicationParser::REGEXP_ID) + "\\.[0-9A-Za-z]+";
2146 class AllowNavigationParser : public ElementParser
2149 AllowNavigationParser(ConfigParserData& data) :
2152 m_properNamespace(false)
2155 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2156 const DPL::String& /*name*/)
2158 return &IgnoringParser::Create; //ignore unknown according to w3c
2161 virtual void Accept(const Element& element)
2163 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2164 m_properNamespace = true;
2168 virtual void Accept(const Text& text)
2170 if (m_properNamespace)
2172 m_origin = text.value;
2176 virtual void Accept(const XmlAttribute& /*attribute*/)
2180 virtual void Verify()
2182 if (m_data.allowNavigationEncountered || !m_properNamespace)
2186 m_data.allowNavigationEncountered = true;
2188 if (m_origin.IsNull()) {
2189 _W("data is empty");
2193 char* data = strdup(DPL::ToUTF8String(*m_origin).c_str());
2194 char* ptr = strtok(data," ");
2195 while (ptr != NULL) {
2196 std::string origin = ptr;
2197 ptr = strtok(NULL," ");
2199 ConfigParserData::AllowNavigationInfo info(L"*", L"*");
2200 m_data.allowNavigationInfoList.push_back(info);
2204 DPL::ScopedPtr<iri_t> iri(iri_parse(origin.c_str()));
2205 if (!iri->host || strlen(iri->host) == 0) {
2206 // input origin should has schem and host
2207 // in case of file scheme path is filled
2209 _W("input origin isn't verified");
2212 DPL::String scheme = L"*";
2213 if (iri->scheme && strlen(iri->scheme) != 0) {
2214 scheme = DPL::FromUTF8String(iri->scheme);
2216 ConfigParserData::AllowNavigationInfo info(
2218 DPL::FromUTF8String(iri->host));
2219 m_data.allowNavigationInfoList.push_back(info);
2225 DPL::OptionalString m_origin;
2226 ConfigParserData& m_data;
2227 bool m_properNamespace;
2230 class CspParser : public ElementParser
2233 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2234 const DPL::String& /*name*/)
2236 return &IgnoringParser::Create; //ignore unknown according to w3c
2239 CspParser(ConfigParserData& data) :
2242 m_properNamespace(false)
2245 virtual void Accept(const Element& element)
2247 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2248 m_properNamespace = true;
2252 virtual void Accept(const XmlAttribute& /*attribute*/)
2255 virtual void Accept(const Text& text)
2257 if (m_properNamespace) {
2258 m_policy = text.value;
2262 virtual void Verify()
2264 if (!m_policy.IsNull()) {
2265 m_data.cspPolicy = *m_policy;
2270 ConfigParserData& m_data;
2271 bool m_properNamespace;
2272 DPL::OptionalString m_policy;
2275 class CspReportOnlyParser : public ElementParser
2278 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2279 const DPL::String& /*name*/)
2281 return &IgnoringParser::Create; //ignore unknown according to w3c
2284 CspReportOnlyParser(ConfigParserData& data) :
2287 m_properNamespace(false)
2290 virtual void Accept(const Element& element)
2292 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2293 m_properNamespace = true;
2297 virtual void Accept(const XmlAttribute& /*attribute*/)
2300 virtual void Accept(const Text& text)
2302 if (m_properNamespace) {
2303 m_policy = text.value;
2307 virtual void Verify()
2309 if (!m_policy.IsNull()) {
2310 m_data.cspPolicyReportOnly = *m_policy;
2315 ConfigParserData& m_data;
2316 bool m_properNamespace;
2317 DPL::OptionalString m_policy;
2320 class AccountParser : public ElementParser
2323 struct AccountProviderParser : public ElementParser
2327 struct IconParser : public ElementParser
2330 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2331 const DPL::String& /*name*/)
2333 return &IgnoringParser::Create; //ignore unknown according to w3c
2336 virtual void Accept(const Text& text)
2338 if (text.value == L"") {
2341 m_value = text.value;
2344 virtual void Accept(const Element& /*element*/)
2347 virtual void Accept(const XmlAttribute& attribute)
2349 if (attribute.name == L"section") {
2350 if (attribute.value == L"account") {
2351 m_type = ConfigParserData::IconSectionType::DefaultIcon;
2352 } else if (attribute.value == L"account-small") {
2353 m_type = ConfigParserData::IconSectionType::SmallIcon;
2358 virtual void Verify()
2360 if (m_value.IsNull() || *m_value == L"") {
2364 std::pair<ConfigParserData::IconSectionType, DPL::String> icon;
2365 icon.first = m_type;
2366 icon.second = *m_value;
2368 m_data.m_iconSet.insert(icon);
2371 IconParser(ConfigParserData::AccountProvider& data) :
2373 m_properNamespace(false),
2374 m_type(ConfigParserData::DefaultIcon),
2379 bool m_properNamespace;
2380 ConfigParserData::IconSectionType m_type;
2381 ConfigParserData::AccountProvider& m_data;
2382 DPL::OptionalString m_value;
2385 struct DisplayNameParser : public ElementParser
2388 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2389 const DPL::String& /*name*/)
2391 return &IgnoringParser::Create; //ignore unknown according to w3c
2394 virtual void Accept(const Text& text)
2396 if (text.value == L"") {
2399 m_value = text.value;
2402 virtual void Accept(const Element& element)
2404 m_lang = element.lang;
2408 virtual void Accept(const XmlAttribute& /*attribute*/)
2411 virtual void Verify()
2413 if (m_value.IsNull() || *m_value == L"") {
2417 std::pair<DPL::String, DPL::String> name;
2418 name.first = *m_lang;
2419 name.second = *m_value;
2421 m_data.m_displayNameSet.insert(name);
2424 DisplayNameParser(ConfigParserData::AccountProvider& data) :
2426 m_properNamespace(false),
2431 bool m_properNamespace;
2432 DPL::OptionalString m_lang;
2433 DPL::OptionalString m_value;
2434 ConfigParserData::AccountProvider& m_data;
2437 struct CapabilityParser : public ElementParser
2440 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2441 const DPL::String& /*name*/)
2443 return &IgnoringParser::Create; //ignore unknown according to w3c
2446 virtual void Accept(const Text& text)
2448 if (text.value == L"") {
2451 m_value = text.value;
2454 virtual void Accept(const Element& /*element*/)
2457 virtual void Accept(const XmlAttribute& /*attribute*/)
2460 virtual void Verify()
2462 if (m_value.IsNull() || *m_value == L"") {
2465 m_data.m_capabilityList.push_back(*m_value);
2468 CapabilityParser(ConfigParserData::AccountProvider& data) :
2470 m_properNamespace(false),
2475 bool m_properNamespace;
2476 DPL::OptionalString m_value;
2477 ConfigParserData::AccountProvider& m_data;
2479 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2480 const DPL::String& name)
2482 if (name == L"icon") {
2483 return DPL::MakeDelegate(this, &AccountProviderParser::OnIconElement);
2484 } else if (name == L"display-name") {
2485 return DPL::MakeDelegate(this,
2486 &AccountProviderParser::OnDisplayNameElement);
2487 } else if (name == L"capability") {
2488 return DPL::MakeDelegate(this, &AccountProviderParser::OnCapabilityElement);
2490 return &IgnoringParser::Create; //ignore unknown according to w3c
2494 virtual void Accept(const Text& /*text*/)
2497 virtual void Accept(const Element& /*element*/)
2500 virtual void Accept(const XmlAttribute& attribute)
2502 if (attribute.name == L"multiple-accounts-support") {
2503 if (attribute.value == L"true") {
2504 m_multiSupport = true;
2509 virtual void Verify()
2511 m_data.m_multiAccountSupport = m_multiSupport;
2514 ElementParserPtr OnIconElement()
2516 return ElementParserPtr(new IconParser(m_data));
2519 ElementParserPtr OnDisplayNameElement()
2521 return ElementParserPtr(new DisplayNameParser(m_data));
2524 ElementParserPtr OnCapabilityElement()
2526 return ElementParserPtr(new CapabilityParser(m_data));
2529 AccountProviderParser(ConfigParserData::AccountProvider& data) :
2531 m_properNamespace(false),
2532 m_multiSupport(false),
2537 bool m_properNamespace;
2538 bool m_multiSupport;
2539 ConfigParserData::AccountProvider& m_data;
2542 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2543 const DPL::String& name)
2545 if (name == L"account-provider") {
2546 return DPL::MakeDelegate(this, &AccountParser::OnProviderElement);
2548 return &IgnoringParser::Create; //ignore unknown according to w3c
2552 virtual void Accept(const Element& element)
2554 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2555 m_properNamespace = true;
2559 virtual void Accept(const XmlAttribute& /*attribute*/)
2562 virtual void Accept(const Text& /*text*/)
2565 virtual void Verify()
2568 ElementParserPtr OnProviderElement()
2570 return ElementParserPtr(new AccountProviderParser(m_account));
2573 AccountParser(ConfigParserData& data) :
2576 m_account(data.accountProvider),
2577 m_properNamespace(false),
2578 m_multiSupport(false)
2582 ConfigParserData& m_data;
2583 ConfigParserData::AccountProvider& m_account;
2584 bool m_properNamespace;
2585 bool m_multiSupport;
2588 class MetadataParser : public ElementParser
2591 virtual ActionFunc GetElementParser(const DPL::String& /*ns*/,
2592 const DPL::String& /*name*/)
2594 return &IgnoringParser::Create; //ignore unknown according to w3c
2597 virtual void Accept(const XmlAttribute& attribute)
2599 if (m_properNamespace) {
2600 if (attribute.name == L"key") {
2601 m_key = attribute.value;
2602 } else if (attribute.name == L"value") {
2603 m_value = attribute.value;
2608 virtual void Accept(const Element& element)
2610 if (element.ns == ConfigurationNamespace::TizenWebAppNamespaceName) {
2611 m_properNamespace = true;
2615 virtual void Accept(const Text& /*text*/)
2617 ThrowMsg(Exception::ParseError, "param element must be empty");
2620 virtual void Verify()
2622 if (m_key.IsNull()) {
2623 _W("metadata element must have key attribute");
2626 NormalizeString(m_key);
2627 NormalizeString(m_value);
2628 ConfigParserData::Metadata metaData(m_key, m_value);
2629 FOREACH(it, m_data.metadataList) {
2630 if (!DPL::StringCompare(*it->key, *m_key)) {
2631 _E("Key isn't unique");
2635 m_data.metadataList.push_back(metaData);
2638 MetadataParser(ConfigParserData& data) :
2641 m_properNamespace(false)
2645 DPL::OptionalString m_key;
2646 DPL::OptionalString m_value;
2647 ConfigParserData& m_data;
2648 bool m_properNamespace;
2651 ElementParser::ActionFunc WidgetParser::GetElementParser(
2652 const DPL::String& /*ns*/,
2653 const DPL::String& name)
2655 FuncMap::const_iterator it = m_map.find(name);
2656 if (it != m_map.end()) {
2659 return &IgnoringParser::Create; //ignore unknown according to w3c
2663 WidgetParser::WidgetParser(ConfigParserData& data) :
2665 m_textDirection(Unicode::EMPTY)
2667 m_map[L"name"] = DPL::MakeDelegate(this, &WidgetParser::OnNameElement);
2668 m_map[L"access"] = DPL::MakeDelegate(this, &WidgetParser::OnAccessElement);
2669 m_map[L"description"] =
2670 DPL::MakeDelegate(this, &WidgetParser::OnDescriptionElement);
2671 m_map[L"author"] = DPL::MakeDelegate(this, &WidgetParser::OnAuthorElement);
2673 DPL::MakeDelegate(this, &WidgetParser::OnLicenseElement);
2674 m_map[L"icon"] = DPL::MakeDelegate(this, &WidgetParser::OnIconElement);
2676 DPL::MakeDelegate(this, &WidgetParser::OnContentElement);
2677 m_map[L"preference"] =
2678 DPL::MakeDelegate(this, &WidgetParser::OnPreferenceElement);
2680 DPL::MakeDelegate(this, &WidgetParser::OnSettingElement);
2681 m_map[L"application"] = DPL::MakeDelegate(
2684 OnApplicationElement);
2685 m_map[L"splash"] = DPL::MakeDelegate(this, &WidgetParser::OnSplashElement);
2686 m_map[L"background"] = DPL::MakeDelegate(this,
2687 &WidgetParser::OnBackgroundElement);
2688 m_map[L"privilege"] = DPL::MakeDelegate(this,
2689 &WidgetParser::OnPrivilegeElement);
2690 m_map[L"app-control"] = DPL::MakeDelegate(
2693 OnAppControlElement);
2694 m_map[L"category"] = DPL::MakeDelegate(this,
2695 &WidgetParser::OnCategoryElement);
2696 m_map[L"app-widget"] = DPL::MakeDelegate(this, &WidgetParser::OnAppWidgetElement);
2698 m_map[L"content-security-policy"] = DPL::MakeDelegate(
2702 m_map[L"content-security-policy-report-only"] = DPL::MakeDelegate(
2705 OnCspReportOnlyElement);
2707 #ifdef ALLOW_NAVIGATION_ENABLED
2708 m_map[L"allow-navigation"] =
2709 DPL::MakeDelegate(this, &WidgetParser::OnAllowNavigationElement);
2711 m_map[L"account"] = DPL::MakeDelegate(this, &WidgetParser::OnAccountElement);
2712 m_map[L"metadata"] = DPL::MakeDelegate(this, &WidgetParser::OnMetadataElement);
2715 ElementParserPtr WidgetParser::OnNameElement()
2717 return ElementParserPtr(new NameParser(m_textDirection, m_data));
2720 ElementParserPtr WidgetParser::OnAccessElement()
2722 return ElementParserPtr(new AccessParser(m_data));
2725 ElementParserPtr WidgetParser::OnDescriptionElement()
2727 return ElementParserPtr(new DescriptionParser(m_textDirection, m_data));
2730 ElementParserPtr WidgetParser::OnAuthorElement()
2732 return ElementParserPtr(new AuthorParser(m_textDirection, m_data));
2735 ElementParserPtr WidgetParser::OnLicenseElement()
2737 return ElementParserPtr(new LicenseParser(m_textDirection, m_data));
2740 ElementParserPtr WidgetParser::OnIconElement()
2742 return ElementParserPtr(new IconParser(m_data));
2745 ElementParserPtr WidgetParser::OnContentElement()
2747 return ElementParserPtr(new ContentParser(m_data));
2750 ElementParserPtr WidgetParser::OnPreferenceElement()
2752 return ElementParserPtr(new PreferenceParser(m_data));
2755 ElementParserPtr WidgetParser::OnSettingElement()
2757 return ElementParserPtr(new SettingParser(m_data));
2760 ElementParserPtr WidgetParser::OnApplicationElement()
2762 return ElementParserPtr(new ApplicationParser(m_data));
2765 ElementParserPtr WidgetParser::OnSplashElement()
2767 return ElementParserPtr(new SplashParser(m_data));
2770 ElementParserPtr WidgetParser::OnBackgroundElement()
2772 return ElementParserPtr(new BackgroundParser(m_data));
2775 ElementParserPtr WidgetParser::OnPrivilegeElement()
2777 return ElementParserPtr(new PrivilegeParser(m_data));
2780 ElementParserPtr WidgetParser::OnAppControlElement()
2782 return ElementParserPtr(new AppControlParser(m_data));
2785 ElementParserPtr WidgetParser::OnCategoryElement()
2787 return ElementParserPtr(new CategoryParser(m_data));
2790 ElementParserPtr WidgetParser::OnAppWidgetElement()
2792 return ElementParserPtr(new AppWidgetParser(m_data));
2795 ElementParserPtr WidgetParser::OnCspElement()
2797 return ElementParserPtr(new CspParser(m_data));
2800 ElementParserPtr WidgetParser::OnCspReportOnlyElement()
2802 return ElementParserPtr(new CspReportOnlyParser(m_data));
2805 ElementParserPtr WidgetParser::OnAllowNavigationElement()
2807 return ElementParserPtr(new AllowNavigationParser(m_data));
2810 ElementParserPtr WidgetParser::OnAccountElement()
2812 return ElementParserPtr(new AccountParser(m_data));
2815 ElementParserPtr WidgetParser::OnMetadataElement()
2817 return ElementParserPtr(new MetadataParser(m_data));
2820 void WidgetParser::Accept(const Element& element)
2822 if (element.ns != ConfigurationNamespace::W3CWidgetNamespaceName &&
2823 element.ns != ConfigurationNamespace::TizenWebAppNamespaceName)
2825 ThrowMsg(Exception::ParseError,
2826 "Wrong xml namespace for widget element");
2830 void WidgetParser::Accept(const Text& /*text*/)
2832 ThrowMsg(Exception::ParseError, "widged element must be empty");
2835 void WidgetParser::Accept(const XmlAttribute& attribute)
2837 if (attribute.name == L"id") {
2838 LibIri::Wrapper iri(DPL::ToUTF8String(attribute.value).c_str());
2839 //If may important tests starts to fail this test we will have
2840 //to consider commenting this test out again.
2841 if (iri.Validate()) {
2842 m_data.widget_id = attribute.value;
2843 NormalizeString(m_data.widget_id);
2845 _W("Widget id validation failed: %ls", attribute.value.c_str());
2847 } else if (attribute.name == L"version") {
2848 m_version = attribute.value;
2849 NormalizeString(m_version);
2850 } else if (attribute.name == L"min-version") {
2851 _D("min-version attribute was found. Value: %ls", attribute.value.c_str());
2852 m_minVersion = attribute.value;
2853 NormalizeString(m_minVersion);
2854 m_data.minVersionRequired = m_minVersion;
2855 } else if (attribute.name == L"height") {
2856 DPL::OptionalString value = attribute.value;
2857 NormalizeString(value);
2858 std::string v = DPL::ToUTF8String(*value);
2861 unsigned char c = v.c_str()[0];
2864 for (size_t i = 0; i < v.size(); ++i) {
2873 m_data.height = val;
2876 } else if (attribute.name == L"width") {
2877 DPL::OptionalString value = attribute.value;
2878 NormalizeString(value);
2879 std::string v = DPL::ToUTF8String(*value);
2882 unsigned char c = v.c_str()[0];
2883 if (c >= '0' && c <= '9') {
2885 for (size_t i = 0; i < v.size(); ++i) {
2887 if (c >= '0' && c <= '9') {
2897 } else if (attribute.name == L"viewmodes") {
2898 DPL::Tokenize(attribute.value,
2900 std::inserter(m_windowModes,
2901 m_windowModes.end()),
2903 } else if (attribute.name == L"dir") {
2904 m_textDirection = Unicode::ParseDirAttribute(attribute);
2905 } else if (L"defaultlocale" == attribute.name) {
2906 if (!m_defaultlocale) {
2907 m_defaultlocale = attribute.value;
2908 NormalizeString(m_defaultlocale);
2909 if( I18n::DB::I18nDAOReadOnly::IsValidSubTag
2910 (attribute.value, RECORD_TYPE_LANGUAGE)) {
2911 _D("Default Locale Found %ls", (*m_defaultlocale).c_str());
2913 _W("Default Locate Is Invalid");
2916 _W("Ignoring subsequent default locale");
2919 //Any other value consider as a namespace definition
2920 } else if (attribute.name == L"xmlns" || attribute.prefix == L"xmlns") {
2921 _D("Namespace domain: %ls", attribute.name.c_str());
2922 _D("Namespace value: %ls", attribute.value.c_str());
2923 m_nameSpaces[attribute.name] = attribute.value;
2925 _E("Unknown attirbute: namespace=%ls, name=%ls, value=%ls",
2926 attribute.ns.c_str(), attribute.name.c_str(), attribute.value.c_str());
2930 void WidgetParser::Verify()
2932 FOREACH(mode, m_windowModes) {
2933 if (L"windowed" == *mode || L"floating" == *mode ||
2934 L"fullscreen" == *mode || L"maximized" == *mode ||
2935 L"minimized" == *mode)
2937 m_data.windowModes.insert(*mode);
2940 if (!m_version.IsNull()) {
2941 Unicode::UpdateTextWithDirectionMark(m_textDirection, &*m_version);
2942 m_data.version = m_version;
2944 m_data.defaultlocale = m_defaultlocale;
2945 FOREACH(ns, m_nameSpaces) {
2946 m_data.nameSpaces.insert(ns->second);