1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "wgt/extension_config_parser.h"
6 #include <manifest_parser/utils/string_util.h>
7 #include <manifest_parser/manifest_handler.h>
15 const xmlChar kExtensionNodeKey[] = "extension";
16 const xmlChar kNamePrivilegeKey[] = "privilege";
17 const xmlChar kPrivigeNameAttributeKey[] = "name";
18 const char kAttributePrefix[] = "@";
19 const xmlChar kDirAttributeKey[] = "dir";
20 const char kXmlTextKey[] = "#text";
21 const char kNamespaceKey[] = "@namespace";
22 const char kExtensionPath[] = "extension.privilege";
23 const char kExtensionNameKey[] = "@name";
26 ExtensionConfigParser::ExtensionConfigParser(std::string config_xml)
27 : config_xml_(config_xml) {}
29 std::unique_ptr<parser::DictionaryValue>
30 ExtensionConfigParser::LoadExtensionConfig(const std::string& config_xml) {
31 xmlDoc *doc = nullptr;
32 xmlNode* root_node = nullptr;
33 doc = xmlReadFile(config_xml.c_str(), nullptr, XML_PARSE_NOENT);
35 LOG(ERROR) << "Failed to read xml document model from" << config_xml;
38 root_node = xmlDocGetRootElement(doc);
39 std::unique_ptr<parser::DictionaryValue> dv = LoadXMLNode(root_node);
40 std::unique_ptr<parser::DictionaryValue> result(new parser::DictionaryValue);
42 result->Set(reinterpret_cast<const char*>(root_node->name), dv.release());
46 std::string ExtensionConfigParser::GetNodeDir(
47 xmlNode* node, const std::string& inherit_dir) {
48 std::string dir(inherit_dir);
49 for (xmlAttr* prop = node->properties; prop; prop = prop->next) {
50 if (xmlStrEqual(prop->name, kDirAttributeKey)) {
51 char* prop_value = reinterpret_cast<char*>(xmlNodeListGetString(
52 node->doc, prop->children, 1));
60 std::string ExtensionConfigParser::GetNodeText(
61 xmlNode* root, const std::string& inherit_dir) {
62 if (root->type != XML_ELEMENT_NODE)
64 std::string current_dir(GetNodeDir(root, inherit_dir));
66 if (!current_dir.empty())
67 text += parser::utils::GetDirUTF8Start(current_dir);
68 for (xmlNode* node = root->children; node; node = node->next) {
69 if (node->type == XML_TEXT_NODE || node->type == XML_CDATA_SECTION_NODE)
70 text = text + std::string(reinterpret_cast<char*>(node->content));
72 text += GetNodeText(node, current_dir);
74 if (!current_dir.empty())
75 text += parser::utils::GetDirUTF8End();
78 bool ExtensionConfigParser::IsPropSupportDir(xmlNode* root, xmlAttr* prop) {
79 if (xmlStrEqual(root->name, kNamePrivilegeKey)
80 && xmlStrEqual(prop->name, kPrivigeNameAttributeKey)) {
85 bool ExtensionConfigParser::IsTrimRequiredForElement(xmlNode* root) {
86 if (xmlStrEqual(root->name, kNamePrivilegeKey)) {
91 bool ExtensionConfigParser::IsTrimRequiredForProp(
92 xmlNode* root, xmlAttr* prop) {
93 if (xmlStrEqual(root->name, kNamePrivilegeKey) &&
94 xmlStrEqual(prop->name, kPrivigeNameAttributeKey)) {
99 std::unique_ptr<parser::DictionaryValue>
100 ExtensionConfigParser::LoadXMLNode(
101 xmlNode* root, const std::string& inherit_dir) {
102 std::unique_ptr<parser::DictionaryValue> value(new parser::DictionaryValue());
103 if (root->type != XML_ELEMENT_NODE)
106 std::string current_dir(GetNodeDir(root, inherit_dir));
108 xmlAttr* prop = nullptr;
109 for (prop = root->properties; prop; prop = prop->next) {
110 xmlChar* value_ptr = xmlNodeListGetString(root->doc, prop->children, 1);
111 std::string prop_value(reinterpret_cast<char*>(value_ptr));
113 if (IsPropSupportDir(root, prop))
114 prop_value = parser::utils::GetDirTextUTF8(prop_value, current_dir);
116 if (IsTrimRequiredForProp(root, prop))
117 prop_value = parser::utils::CollapseWhitespaceUTF8(prop_value);
120 std::string(kAttributePrefix)
121 + reinterpret_cast<const char*>(prop->name),
126 value->SetString(kNamespaceKey,
127 reinterpret_cast<const char*>(root->ns->href));
129 for (xmlNode* node = root->children; node; node = node->next) {
130 std::string sub_node_name(reinterpret_cast<const char*>(node->name));
131 std::unique_ptr<parser::DictionaryValue> sub_value =
132 LoadXMLNode(node, current_dir);
137 if (!value->HasKey(sub_node_name)) {
138 value->Set(sub_node_name, sub_value.release());
143 value->Get(sub_node_name, &temp);
145 if (temp->IsType(parser::Value::TYPE_LIST)) {
146 parser::ListValue* list;
147 temp->GetAsList(&list);
148 list->Append(sub_value.release());
150 assert(temp->IsType(parser::Value::TYPE_DICTIONARY));
151 parser::DictionaryValue* dict;
152 temp->GetAsDictionary(&dict);
153 parser::DictionaryValue* prev_value = dict->DeepCopy();
155 parser::ListValue* list = new parser::ListValue();
156 list->Append(prev_value);
157 list->Append(sub_value.release());
158 value->Set(sub_node_name, list);
163 xmlChar* text_ptr = xmlNodeListGetString(root->doc, root->children, 1);
165 text = reinterpret_cast<char*>(text_ptr);
168 if (IsTrimRequiredForElement(root))
169 text = parser::utils::CollapseWhitespaceUTF8(text);
171 value->SetString(kXmlTextKey, text);
175 std::vector<std::string> ExtensionConfigParser::GetExtensionPrivilegeList() {
176 std::unique_ptr<parser::DictionaryValue> dic
177 = LoadExtensionConfig(config_xml_);
178 std::vector<std::string> privilege_list;
180 for (auto& item : parser::GetOneOrMany(dic.get(), kExtensionPath, "")) {
181 std::string privilege;
182 if (item->GetString(kExtensionNameKey, &privilege)) {
183 LOG(DEBUG) << "User defined extra privilege: " << privilege;
184 privilege_list.push_back(privilege);
187 return privilege_list;