Fix static analysis issue
[platform/core/appfw/app-installers.git] / src / common / plugins / tag_plugin.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/plugins/tag_plugin.h"
6
7 #include <map>
8 #include <utility>
9
10 namespace common_installer {
11
12 const char TagPlugin::kType[] = "tag";
13
14 std::unique_ptr<TagPlugin> TagPlugin::Create(
15     const PluginInfo& plugin_info, Plugin::ActionType action_type) {
16   std::unique_ptr<TagPlugin> plugin(new TagPlugin(plugin_info, action_type));
17   if (!plugin->Load())
18     return nullptr;
19   return plugin;
20 }
21
22 std::string TagPlugin::GetFunctionName(ProcessType process,
23                                        ActionType action) const {
24   static std::map<std::pair<ActionType, ProcessType>, std::string> names {
25     {{ActionType::Install,   ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_INSTALL"},   // NOLINT
26     {{ActionType::Upgrade,   ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_UPGRADE"},   // NOLINT
27     {{ActionType::Uninstall, ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL"}, // NOLINT
28     {{ActionType::RecoverInstall, ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_RECOVERINSTALL"}, // NOLINT
29     {{ActionType::RecoverUpgrade, ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_RECOVERUPGRADE"}, // NOLINT
30     {{ActionType::RecoverUninstall, ProcessType::Pre},  "PKGMGR_PARSER_PLUGIN_PRE_RECOVERUNINSTALL"}, // NOLINT
31     {{ActionType::Install,   ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_INSTALL"},       // NOLINT
32     {{ActionType::Upgrade,   ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_UPGRADE"},       // NOLINT
33     {{ActionType::Uninstall, ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_UNINSTALL"},     // NOLINT
34     {{ActionType::Removed, ProcessType::Main}, "PKGMGR_PARSER_PLUGIN_REMOVED"},     // NOLINT
35     {{ActionType::RecoverInstall, ProcessType::Main},  "PKGMGR_PARSER_PLUGIN_RECOVERINSTALL"}, // NOLINT
36     {{ActionType::RecoverUpgrade, ProcessType::Main},  "PKGMGR_PARSER_PLUGIN_RECOVERUPGRADE"}, // NOLINT
37     {{ActionType::RecoverUninstall, ProcessType::Main},  "PKGMGR_PARSER_PLUGIN_RECOVERUNINSTALL"}, // NOLINT
38     {{ActionType::Clean, ProcessType::Main},  "PKGMGR_PARSER_PLUGIN_CLEAN"}, // NOLINT
39     {{ActionType::Undo, ProcessType::Main},  "PKGMGR_PARSER_PLUGIN_UNDO"}, // NOLINT
40     {{ActionType::Install,   ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_INSTALL"},  // NOLINT
41     {{ActionType::Upgrade,   ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_UPGRADE"},  // NOLINT
42     {{ActionType::Uninstall, ProcessType::Post}, "PKGMGR_PARSER_PLUGIN_POST_UNINSTALL"}, // NOLINT
43     {{ActionType::RecoverInstall, ProcessType::Post},  "PKGMGR_PARSER_PLUGIN_POST_RECOVERINSTALL"}, // NOLINT
44     {{ActionType::RecoverUpgrade, ProcessType::Post},  "PKGMGR_PARSER_PLUGIN_POST_RECOVERUPGRADE"}, // NOLINT
45     {{ActionType::RecoverUninstall, ProcessType::Post},  "PKGMGR_PARSER_PLUGIN_POST_RECOVERUNINSTALL"}, // NOLINT
46   };
47
48   auto pos = names.find(std::make_pair(action, process));
49   if (pos == names.end()) {
50     LOG(INFO) << "Function name not defined";
51     return "";
52   }
53   return pos->second;
54 }
55
56 xmlNodePtr MakePluginNode(xmlNodePtr node, const std::string& tag_name) {
57     xmlNodePtr ret_node = nullptr;
58     if (tag_name == reinterpret_cast<const char*>(node->name)) {
59         ret_node = xmlCopyNode(node, 1);
60         return ret_node;
61     }
62
63     for (xmlNodePtr child = xmlFirstElementChild(node);
64         child != nullptr; child = xmlNextElementSibling(child)) {
65       xmlNodePtr child_node = MakePluginNode(child, tag_name);
66       if (!child_node)
67         continue;
68       if (!ret_node)
69         ret_node = xmlCopyNode(node, 0);
70       xmlAddChild(ret_node, child_node);
71     }
72     return ret_node;
73 }
74
75 xmlDocPtr TagPlugin::CreateDocPtrForPlugin(xmlDocPtr doc_ptr,
76     const std::string& tag_name) const {
77   // Make copy of document and root node
78   xmlNodePtr root_node = xmlDocGetRootElement(doc_ptr);
79   if (!root_node) {
80     LOG(ERROR) << "Original document is empty. Cannot create copy for plugin";
81     return nullptr;
82   }
83   xmlDocPtr plugin_doc_ptr = xmlCopyDoc(doc_ptr, 0);
84   xmlNodePtr plugin_root_node = MakePluginNode(root_node, tag_name);
85   if (!plugin_root_node) {
86     LOG(ERROR) << "make plugin node fail";
87     xmlFreeDoc(plugin_doc_ptr);
88     return nullptr;
89   }
90   xmlDocSetRootElement(plugin_doc_ptr, plugin_root_node);
91   xmlSetTreeDoc(plugin_root_node, plugin_doc_ptr);
92   return plugin_doc_ptr;
93 }
94
95 bool TagPlugin::Run(xmlDocPtr doc_ptr, manifest_x* manifest,
96          ActionType action_type) {
97   xmlDocPtr plugin_doc_ptr = CreateDocPtrForPlugin(doc_ptr,
98                                                    plugin_info_.name());
99   if (!plugin_doc_ptr && action_type_ != Plugin::ActionType::Removed)
100     return false;
101
102   int result = 0;
103   ActionType type =
104       (action_type_ != ActionType::Unknown &&
105        action_type != ActionType::Undo &&
106        action_type != ActionType::Clean) ? action_type_ : action_type;
107   std::string pre_function = GetFunctionName(ProcessType::Pre, type);
108   Exec(pre_function, &result, manifest->package);
109   if (result) {
110     LOG(ERROR) << "Function: " << pre_function << " of plugin "
111                << plugin_info_.path() << " failed";
112     xmlFreeDoc(plugin_doc_ptr);
113     return false;
114   }
115
116   std::string main_function = GetFunctionName(ProcessType::Main, type);
117   Exec(main_function, &result, plugin_doc_ptr, manifest->package);
118   if (result) {
119     LOG(ERROR) << "Function: " << main_function << " of plugin "
120                << plugin_info_.path() << " failed";
121     xmlFreeDoc(plugin_doc_ptr);
122     return false;
123   }
124
125   std::string post_function = GetFunctionName(ProcessType::Post, type);
126   Exec(post_function, &result, manifest->package);
127   if (result) {
128     LOG(ERROR) << "Function: " << post_function << " of plugin "
129                << plugin_info_.path() << " failed";
130     xmlFreeDoc(plugin_doc_ptr);
131     return false;
132   }
133
134   xmlFreeDoc(plugin_doc_ptr);
135   return true;
136 }
137
138
139 }  // namespace common_installer