Add step StepRunParserPlugin 34/57334/26
authorLukasz Wartalowicz <l.wartalowic@samsung.com>
Mon, 18 Jan 2016 14:56:59 +0000 (15:56 +0100)
committerTomasz Iwanek <t.iwanek@samsung.com>
Thu, 28 Jan 2016 09:57:48 +0000 (01:57 -0800)
Change-Id: Ib644cf44a47879750c99026974f8c83909eb8a66

packaging/app-installers.spec
src/common/CMakeLists.txt
src/common/plugins_list.txt.in [new file with mode: 0644]
src/common/step/step_run_parser_plugins.cc [new file with mode: 0644]
src/common/step/step_run_parser_plugins.h [new file with mode: 0644]
src/common/utils/plugin_list_parser.cc [new file with mode: 0644]
src/common/utils/plugin_list_parser.h [new file with mode: 0644]
src/common/utils/plugin_manager.cc [new file with mode: 0644]
src/common/utils/plugin_manager.h [new file with mode: 0644]
src/common/utils/plugin_xml_parser.cc [new file with mode: 0644]
src/common/utils/plugin_xml_parser.h [new file with mode: 0644]

index 507d64d3abc170c1fb1652e8b943cde50ce471cb..68f5a1787f48e3d71c0047433123012b9f62c9a5 100644 (file)
@@ -78,6 +78,7 @@ ln -sf %{_bindir}/pkgdir-tool %{_bindir}/pkgdir_maker
 
 %files
 %defattr(-,root,root)
+%{_datarootdir}/app-installers/plugins_list.txt
 %manifest app-installers.manifest
 %{_libdir}/libapp-installers.so*
 %attr(6750,root,users) %{_bindir}/pkgdir-tool
index 02093eb39da2307e4d51a2599df7657cb7c521a0..d79d3fd834589245803b317c7df60fb95ac86a53 100644 (file)
@@ -44,6 +44,7 @@ SET(SRCS
   step/step_register_security.cc
   step/step_rollback_deinstallation_security.cc
   step/step_rollback_installation_security.cc
+  step/step_run_parser_plugins.cc
   step/step_unregister_app.cc
   step/step_update_app.cc
   step/step_update_security.cc
@@ -51,6 +52,9 @@ SET(SRCS
   utils/dynamic_lib_handle.cc
   utils/file_util.cc
   utils/subprocess.cc
+  utils/plugin_xml_parser.cc
+  utils/plugin_list_parser.cc
+  utils/plugin_manager.cc
 )
 # Target - definition
 ADD_LIBRARY(${TARGET_LIBNAME_COMMON} SHARED ${SRCS})
@@ -83,6 +87,18 @@ SET_TARGET_PROPERTIES(${TARGET_LIBNAME_COMMON} PROPERTIES SOVERSION ${VERSION_MA
 # Install
 INSTALL(TARGETS ${TARGET_LIBNAME_COMMON} DESTINATION ${LIB_INSTALL_DIR})
 
+
+# Plugins
+SET(PLUGINS_LIST_FILE_NAME plugins_list.txt)
+SET(PLUGINS_LIST_FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGINS_LIST_FILE_NAME})
+
+SET(PLUGINS_LIST_INSTALL_PATH ${SHAREDIR}/${TARGET_LIBNAME_COMMON})
+SET(PLUGINS_LIST_INSTALL_FILE_PATH ${PLUGINS_LIST_INSTALL_PATH}/${PLUGINS_LIST_FILE_NAME})
+
+ADD_DEFINITIONS("-DPLUGINS_LIST_INSTALL_FILE_PATH=\"${PLUGINS_LIST_INSTALL_FILE_PATH}\"")
+CONFIGURE_FILE(${PLUGINS_LIST_FILE_NAME}.in ${PLUGINS_LIST_FILE_NAME} @ONLY)
+INSTALL(FILES ${PLUGINS_LIST_FILE_PATH} DESTINATION ${PLUGINS_LIST_INSTALL_PATH}/)
+
 # Export devel package
 CONFIGURE_FILE(app-installers.pc.in app-installers.pc @ONLY)
 INSTALL(FILES app-installers.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
diff --git a/src/common/plugins_list.txt.in b/src/common/plugins_list.txt.in
new file mode 100644 (file)
index 0000000..2355da3
--- /dev/null
@@ -0,0 +1,16 @@
+flag="0x00000001";type="tag";name="shortcut-list";path="/usr/etc/package-manager/parserlib/libshortcut-list.so"
+flag="0x00000002";type="tag";name="account";path="/usr/etc/package-manager/parserlib/libaccount.so"
+flag="0x00000004";type="tag";name="notifications";path="/usr/etc/package-manager/parserlib/libnotifications.so"
+flag="0x00000008";type="tag";name="privileges";path="/usr/etc/package-manager/parserlib/libprivileges.so"
+flag="0x00000010";type="tag";name="ime";path="/usr/etc/package-manager/parserlib/libime.so"
+flag="0x00000020";type="category";name="http://tizen.org/category/downloadable_font";path="/usr/etc/package-manager/parserlib/category/libdownloadable_font.so"
+flag="0x00000040";type="metadata";name="http://developer.samsung.com/tizen/metadata/sticker";path="/usr/etc/package-manager/parserlib/metadata/libsticker.so"
+flag="0x00000080";type="metadata";name="http://developer.samsung.com/tizen/metadata/ttsengine";path="/usr/etc/package-manager/parserlib/metadata/libttsengine.so"
+flag="0x00000100";type="metadata";name="http://developer.samsung.com/tizen/metadata/downloadable_filters";path="/usr/etc/package-manager/parserlib/metadata/libdownloadable_filters.so"
+flag="0x00000200";type="metadata";name="http://developer.samsung.com/tizen/metadata/dictionary";path="/usr/etc/package-manager/parserlib/metadata/libdictionary.so"
+flag="0x00000400";type="category";name="http://tizen.org/category/antivirus";path="/usr/etc/package-manager/parserlib/category/libantivirus.so"
+flag="0x00000800";type="metadata";name="http://developer.samsung.com/tizen/metadata/profile";path="/usr/etc/package-manager/parserlib/metadata/libtheme.so"
+flag="0x00001000";type="category";name="http://tizen.org/category/tts";path="/usr/etc/package-manager/parserlib/category/libsamsung_tts.so"
+flag="0x00002000";type="tag";name="livebox";path="/usr/etc/package-manager/parserlib/liblivebox.so"
+flag="0x00004000";type="tag";name="watch-application";path="/usr/etc/package-manager/parserlib/libwatch-application.so"
+flag="0x00008000";type="tag";name="widget-application";path="/usr/etc/package-manager/parserlib/libwidget-application.so"
diff --git a/src/common/step/step_run_parser_plugins.cc b/src/common/step/step_run_parser_plugins.cc
new file mode 100644 (file)
index 0000000..a1b9945
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <string>
+#include <vector>
+
+#include "common/step/step_run_parser_plugins.h"
+
+namespace common_installer {
+namespace pkgmgr {
+
+StepRunParserPlugin::StepRunParserPlugin(InstallerContext* context,
+                                         ActionType action_type)
+    : Step(context), action_type_(action_type) {}
+
+Step::Status StepRunParserPlugin::ProcessingPlugins(
+    const boost::filesystem::path& xml_path) {
+  // PLUGINS_LIST_FILE_PATH path generated from cmake
+  const std::string listPath(PLUGINS_LIST_INSTALL_FILE_PATH);
+
+  // init plugin_manager
+  plugin_manager_.reset(new PluginManager(xml_path.string(), listPath));
+
+  if (!plugin_manager_->GenerateUnknownTagList()) {
+    LOG(ERROR) << "Error during generate unknown list, no exist file, path, "
+                  "invalid data format etc, chceck log";
+    return Status::ERROR;
+  }
+
+  std::vector<std::shared_ptr<PluginInfo>> plugins =
+      plugin_manager_->UnknownTagList();
+
+  for (const std::shared_ptr<PluginInfo>& plugin : plugins) {
+    if (!plugin_manager_->Launch(plugin->path(), action_type_,
+                                 context_->pkgid.get())) {
+      LOG(ERROR) << "Error during launch tag name: " << plugin->name()
+                 << " path: " << plugin->path();
+      return Status::ERROR;
+    }
+    // add plugin to array for undo process
+    if (action_type_ == ActionType::Install) {
+      installed_plugins_.push_back(plugin);
+    }
+  }
+
+  LOG(INFO) << "Successfully processing plugins";
+  return Status::OK;
+}
+
+Step::Status StepRunParserPlugin::process() {
+  return ProcessingPlugins(context_->xml_path.get());
+}
+
+Step::Status StepRunParserPlugin::undo() {
+  if (action_type_ == ActionType::Install) {
+    if (installed_plugins_.empty()) {
+      // no installed plugins
+      return Status::OK;
+    }
+
+    for (const std::shared_ptr<PluginInfo>& plugin : installed_plugins_) {
+      if (!plugin_manager_->Launch(plugin->path(), ActionType::Uninstall,
+                                   context_->pkgid.get())) {
+        LOG(ERROR) << "Error during uninstall tag name: " << plugin->name()
+                   << " path: " << plugin->path();
+      }
+    }
+  } else if (action_type_ == ActionType::Upgrade) {
+    return ProcessingPlugins(context_->backup_xml_path.get());
+  } else if (action_type_ == ActionType::Uninstall) {
+    return ProcessingPlugins(context_->xml_path.get());
+  }
+  return Status::OK;
+}
+
+}  // namespace pkgmgr
+}  // namespace common_installer
diff --git a/src/common/step/step_run_parser_plugins.h b/src/common/step/step_run_parser_plugins.h
new file mode 100644 (file)
index 0000000..9d5fb6e
--- /dev/null
@@ -0,0 +1,40 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_
+#define COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_
+
+#include <string>
+#include <vector>
+
+#include "common/utils/plugin_manager.h"
+#include "manifest_parser/utils/logging.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace pkgmgr {
+
+class StepRunParserPlugin : public Step {
+ public:
+  explicit StepRunParserPlugin(InstallerContext* context,
+                               ActionType action_type);
+
+  Step::Status process() override;
+  Step::Status clean() { return Status::OK; }
+  Step::Status undo() override;
+  Step::Status precheck() { return Status::OK; }
+
+  SCOPE_LOG_TAG(RunParserPlugin)
+
+ private:
+  Step::Status ProcessingPlugins(const boost::filesystem::path& xml_path);
+  ActionType action_type_;
+  std::vector<std::shared_ptr<PluginInfo>> installed_plugins_;
+  std::unique_ptr<PluginManager> plugin_manager_;
+};
+
+}  // namespace pkgmgr
+}  // namespace common_installer
+
+#endif  //  COMMON_STEP_STEP_RUN_PARSER_PLUGINS_H_
diff --git a/src/common/utils/plugin_list_parser.cc b/src/common/utils/plugin_list_parser.cc
new file mode 100644 (file)
index 0000000..c3f99b2
--- /dev/null
@@ -0,0 +1,235 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
+#include "common/utils/plugin_list_parser.h"
+
+namespace common_installer {
+
+PluginInfo::PluginInfo(int flag, const std::string& type,
+                       const std::string& name,
+                       const boost::filesystem::path& path)
+    : flag_(flag),
+      type_(std::move(type)),
+      name_(std::move(name)),
+      path_(std::move(path)) {}
+
+int PluginInfo::flag() const { return flag_; }
+
+const std::string& PluginInfo::type() const { return type_; }
+
+const std::string& PluginInfo::name() const { return name_; }
+
+const boost::filesystem::path& PluginInfo::path() const { return path_; }
+
+// class PluginsListParser
+bool PluginsListParser::ValidType(const std::string& type) {
+  if (type.empty()) {
+    LOG(ERROR) << "Type is empty (valid function)";
+    return false;
+  }
+  std::regex re_valid(R"((tag|metadata|category))");
+  return std::regex_search(type, re_valid);
+}
+
+bool PluginsListParser::ValidFlag(const std::string& flag) {
+  if (flag.empty()) {
+    LOG(ERROR) << "Flag is empty (valid function)";
+    return false;
+  }
+
+  std::regex re_valid(R"(0x[01248]+)");
+  return std::regex_match(flag, re_valid);
+}
+
+bool PluginsListParser::ValidName(const std::string& name) {
+  if (name.empty()) {
+    LOG(ERROR) << "Name is empty (valid function)";
+    return false;
+  }
+
+  return true;
+}
+
+bool PluginsListParser::ValidPath(const std::string& path) {
+  if (path.empty()) {
+    LOG(ERROR) << "Path is empty (valid function)";
+    return false;
+  }
+
+  std::smatch match;
+  std::regex re_extension(R"((\.so[^/]+)?$)");
+
+  if (!std::regex_search(path, match, re_extension)) {
+    return false;
+  }
+
+  // if no matched group
+  if (match.size() != 2) {
+    LOG(ERROR) << "Path not included extension lib file";
+    return false;
+  }
+
+  return true;
+}
+
+std::string PluginsListParser::ExtractRaw(const std::string& data,
+                                          const std::regex& re_extract) {
+  std::smatch match;
+  std::regex_search(data, match, re_extract);
+
+  // 2 mean matched group
+  if (match.size() != 2) {
+    LOG(ERROR) << "Could not find data during extracting parameter";
+    return {};
+  }
+  return match[1];
+}
+
+std::string PluginsListParser::ExtractFlag(const std::string& flag) {
+  std::regex re_extract(R"(flag\s*\=\s*\"(.*)\")");
+  return ExtractRaw(flag, re_extract);
+}
+
+std::string PluginsListParser::ExtractName(const std::string& type) {
+  std::regex re_extract(R"(name\s*\=\s*\"(.*)\")");
+  return ExtractRaw(type, re_extract);
+}
+
+std::string PluginsListParser::ExtractType(const std::string& type) {
+  std::regex re_extract(R"(type\s*\=\s*\"(.*)\")");
+  return ExtractRaw(type, re_extract);
+}
+
+std::string PluginsListParser::ExtractPath(const std::string& path) {
+  std::regex re_extract(R"(path\s*\=\s*\"(.*)\")");
+  return ExtractRaw(path, re_extract);
+}
+
+bool PluginsListParser::Parse() {
+  std::vector<std::string> lines;
+
+  if (!ReadLinesFromFile(&lines)) {
+    LOG(ERROR) << "No read lines from file";
+    return false;
+  }
+
+  if (!ParsePluginsRawData(lines)) {
+    LOG(ERROR) << "No parse data from lines";
+    return false;
+  }
+
+  return true;
+}
+
+const std::vector<std::shared_ptr<PluginInfo>>&
+PluginsListParser::PluginInfoList() {
+  return plugin_info_list_;
+}
+
+bool PluginsListParser::ReadLinesFromFile(std::vector<std::string>* lines) {
+  std::ifstream plugins_file;
+
+  plugins_file.open(path_);
+
+  if (!plugins_file.is_open()) {
+    LOG(ERROR) << "File " << path_ << " no open";
+    return false;
+  }
+
+  LOG(INFO) << "Plugin list path: " << path_;
+
+  std::string line;
+  while (plugins_file >> line) {
+    lines->push_back(line);
+  }
+
+  plugins_file.close();
+
+  if (lines->empty()) {
+    LOG(ERROR) << "No data in file " << path_;
+    return false;
+  }
+
+  return true;
+}
+
+bool PluginsListParser::ParsePluginsRawData(
+    const std::vector<std::string>& lines) {
+  plugin_info_list_.clear();
+
+  std::vector<int> flag_container;
+
+  for (const std::string& line : lines) {
+    std::vector<std::string> parts;
+    if (!SplitPluginLine(line, &parts)) {
+      LOG(ERROR) << "Invalid split plugin line";
+      return false;
+    }
+
+    std::string flag = ExtractFlag(parts.at(Flag));
+    std::string type = ExtractType(parts.at(Type));
+    std::string name = ExtractName(parts.at(Name));
+    std::string path = ExtractPath(parts.at(Path));
+
+    if (!ValidFlag(flag)) {
+      LOG(ERROR) << "Invalid flag: " << flag;
+      return false;
+    }
+
+    const int kConvertStringBase = 16;
+    int _flag = std::strtoul(flag.c_str(), nullptr, kConvertStringBase);
+
+    // flag should be unique
+    if (std::find(flag_container.begin(), flag_container.end(), _flag) !=
+        flag_container.end()) {
+      LOG(ERROR) << "Flag isn't unique, flag:  " << _flag;
+      return false;
+    } else {
+      flag_container.push_back(_flag);
+    }
+
+    if (!ValidType(type)) {
+      LOG(ERROR) << "Invalid type: " << type;
+      return false;
+    }
+
+    if (!ValidName(name)) {
+      LOG(ERROR) << "Invalid name: " << name;
+      return false;
+    }
+
+    if (!ValidPath(path)) {
+      LOG(ERROR) << "Invalid path: " << path;
+      return false;
+    }
+
+    boost::filesystem::path _path = boost::filesystem::path(path);
+
+    plugin_info_list_.push_back(
+        std::make_shared<PluginInfo>(_flag, type, name, _path));
+  }
+
+  return true;
+}
+
+bool PluginsListParser::SplitPluginLine(const std::string& line,
+                                        std::vector<std::string>* parts) {
+  static const char kPartsInLine = 4;
+
+  std::vector<std::string> _parts;
+  boost::algorithm::split(_parts, line, boost::algorithm::is_any_of(";"));
+
+  if (_parts.size() != kPartsInLine) {
+    LOG(ERROR) << "Invalid number of parts";
+    return false;
+  }
+
+  parts->assign(_parts.begin(), _parts.end());
+
+  return true;
+}
+}  // namespace common_installer
diff --git a/src/common/utils/plugin_list_parser.h b/src/common/utils/plugin_list_parser.h
new file mode 100644 (file)
index 0000000..6deed4d
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_UTILS_PLUGIN_LIST_PARSER_H_
+#define COMMON_UTILS_PLUGIN_LIST_PARSER_H_
+
+#include <boost/filesystem/path.hpp>
+
+#include <libxml/parser.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xmlschemas.h>
+
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <regex>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "manifest_parser/utils/logging.h"
+
+namespace common_installer {
+
+/** this class include information about plugin */
+class PluginInfo {
+ public:
+  PluginInfo(int flag, const std::string& type, const std::string& name,
+             const boost::filesystem::path& path);
+  int flag() const;
+  const std::string& type() const;
+  const std::string& name() const;
+  const boost::filesystem::path& path() const;
+
+ private:
+  int flag_;
+  std::string type_;
+  std::string name_;
+  boost::filesystem::path path_;
+};
+
+/** this class parse plugin file */
+class PluginsListParser {
+ public:
+  explicit PluginsListParser(const std::string& path) : path_(path) {}
+
+  bool Parse();
+  const std::vector<std::shared_ptr<PluginInfo>>& PluginInfoList();
+
+ private:
+  enum Column { Flag, Type, Name, Path };
+
+  PluginsListParser() {}
+  const std::string path_;
+  std::vector<std::shared_ptr<PluginInfo>> plugin_info_list_;
+
+  bool ReadLinesFromFile(std::vector<std::string>* lines);
+  bool ParsePluginsRawData(const std::vector<std::string>& lines);
+  bool SplitPluginLine(const std::string& line,
+                       std::vector<std::string>* parts);
+
+  std::string ExtractRaw(const std::string& data, const std::regex& re_extract);
+  std::string ExtractFlag(const std::string& flag);
+  std::string ExtractType(const std::string& type);
+  std::string ExtractName(const std::string& name);
+  std::string ExtractPath(const std::string& path);
+  bool ValidFlag(const std::string& flag);
+  bool ValidType(const std::string& type);
+  bool ValidName(const std::string& name);
+  bool ValidPath(const std::string& path);
+};
+
+}  // namespace common_installer
+#endif  // COMMON_UTILS_PLUGIN_LIST_PARSER_H_
diff --git a/src/common/utils/plugin_manager.cc b/src/common/utils/plugin_manager.cc
new file mode 100644 (file)
index 0000000..7a41bfe
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <boost/filesystem.hpp>
+
+#include <string>
+#include <vector>
+
+#include "common/utils/plugin_list_parser.h"
+#include "common/utils/plugin_xml_parser.h"
+#include "common/utils/plugin_manager.h"
+
+namespace common_installer {
+
+bool PluginManager::GenerateUnknownTagList() {
+  tags_.clear();
+
+  if (!xml_parser_.Parse()) {
+    LOG(ERROR) << "Parse xml function error";
+    return false;
+  }
+
+  std::vector<std::string> xmlTags = xml_parser_.tags_list();
+
+  if (!list_parser_.Parse()) {
+    LOG(ERROR) << "Parse list function error";
+    return false;
+  }
+
+  const std::vector<std::shared_ptr<PluginInfo>> pluginInfoList =
+      list_parser_.PluginInfoList();
+
+  for (std::shared_ptr<PluginInfo> pluginInfo : pluginInfoList) {
+    // find only tags
+    if (pluginInfo->type() == "tag") {
+      // check if a file exist
+      if (boost::filesystem::exists(pluginInfo->path())) {
+        for (const std::string& xmlTag : xmlTags) {
+          // if system tags included in xml tags
+          if (pluginInfo->name() == xmlTag) {
+            tags_.push_back(pluginInfo);
+            LOG(DEBUG) << "Tag: " << pluginInfo->name()
+                       << " path: " << pluginInfo->path() << "has been added";
+            break;
+          }
+        }
+      } else {
+        LOG(WARNING) << "Tag: " << pluginInfo->name()
+                     << " path: " << pluginInfo->path()
+                     << " exist in plugin list but no exist in system.";
+      }
+    }
+  }
+
+  if (tags_.empty()) {
+    LOG(INFO) << "No tags to processing";
+  }
+
+  return true;
+}
+
+const std::vector<std::shared_ptr<PluginInfo>>&
+PluginManager::UnknownTagList() {
+  return tags_;
+}
+
+bool PluginManager::Launch(const boost::filesystem::path& plugin_path,
+                           ActionType action_type, const std::string& pkg_Id) {
+  // TODO(l.wartalowic) add implementation
+  LOG(INFO) << "Launching plugin path:" << plugin_path << " pkgId: " << pkg_Id;
+  (void)plugin_path;
+  (void)action_type;
+  (void)pkg_Id;
+  return true;
+}
+
+}  // namespace common_installer
diff --git a/src/common/utils/plugin_manager.h b/src/common/utils/plugin_manager.h
new file mode 100644 (file)
index 0000000..425bf09
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_UTILS_PLUGIN_MANAGER_H_
+#define COMMON_UTILS_PLUGIN_MANAGER_H_
+
+#include <boost/filesystem/path.hpp>
+
+#include <string>
+#include <vector>
+
+#include "common/utils/plugin_xml_parser.h"
+#include "common/utils/plugin_list_parser.h"
+
+namespace common_installer {
+
+enum class ActionType { Install, Upgrade, Uninstall };
+
+/** this class manages XML and plugin lists */
+class PluginManager {
+ public:
+  PluginManager(const std::string& xml_path, const std::string& list_path)
+      : xml_parser_(xml_path), list_parser_(list_path) {}
+
+  bool GenerateUnknownTagList();
+  const std::vector<std::shared_ptr<PluginInfo>>& UnknownTagList();
+  bool Launch(const boost::filesystem::path& pluginPath, ActionType actionType,
+              const std::string& pkgId);
+
+ private:
+  std::vector<std::shared_ptr<PluginInfo>> tags_;
+  PluginsXmlParser xml_parser_;
+  PluginsListParser list_parser_;
+};
+}  // namespace common_installer
+
+#endif  // COMMON_UTILS_PLUGIN_MANAGER_H_
diff --git a/src/common/utils/plugin_xml_parser.cc b/src/common/utils/plugin_xml_parser.cc
new file mode 100644 (file)
index 0000000..a92e6da
--- /dev/null
@@ -0,0 +1,86 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "manifest_parser/utils/logging.h"
+#include "common/utils/plugin_xml_parser.h"
+
+namespace common_installer {
+
+bool PluginsXmlParser::Parse() {
+  if (path_.empty()) {
+    return false;
+  }
+
+  WrapperXMLReader obj_reader;
+
+  xmlTextReaderPtr reader = obj_reader.Create(path_.c_str());
+
+  if (!reader) {
+    return false;
+  }
+
+  LOG(INFO) << "Xml path: " << path_;
+
+  tags_.clear();
+
+  int depth = xmlTextReaderDepth(reader);
+
+  // use set to remove duplicate
+  std::set<std::string> tags;
+
+  while ((NextChildElement(reader, depth))) {
+    const xmlChar* node = xmlTextReaderConstName(reader);
+
+    if (!node) {
+      return false;
+    }
+
+    tags.insert(std::string(reinterpret_cast<const char*>(node)));
+  }
+
+  tags_.assign(tags.begin(), tags.end());
+
+  // get here, after end of a "reading" file
+  doc_ptr_ = xmlTextReaderCurrentDoc(reader);
+
+  if (!doc_ptr_) {
+    return false;
+  }
+
+  return true;
+}
+
+const std::vector<std::string>& PluginsXmlParser::tags_list() { return tags_; }
+
+xmlDocPtr PluginsXmlParser::doc_ptr() { return doc_ptr_; }
+
+int PluginsXmlParser::NextChildElement(xmlTextReaderPtr reader, int depth) {
+  int ret = xmlTextReaderRead(reader);
+  int cur = xmlTextReaderDepth(reader);
+
+  while (ret == 1) {
+    switch (xmlTextReaderNodeType(reader)) {
+      case XML_READER_TYPE_ELEMENT:
+        if (cur == depth + 1) return 1;
+        break;
+      default:
+
+        if (cur <= depth) return 0;
+        break;
+    }
+
+    ret = xmlTextReaderRead(reader);
+    cur = xmlTextReaderDepth(reader);
+  }
+
+  return ret;
+}
+
+PluginsXmlParser::~PluginsXmlParser() {
+  if (doc_ptr_) {
+    xmlFreeDoc(doc_ptr_);
+  }
+}
+
+}  // namespace common_installer
diff --git a/src/common/utils/plugin_xml_parser.h b/src/common/utils/plugin_xml_parser.h
new file mode 100644 (file)
index 0000000..112960d
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_UTILS_PLUGIN_XML_PARSER_H_
+#define COMMON_UTILS_PLUGIN_XML_PARSER_H_
+
+#include <libxml2/libxml/xmlreader.h>
+
+#include <string>
+#include <vector>
+#include <set>
+
+namespace common_installer {
+
+/** this class parse xml file*/
+class PluginsXmlParser {
+ public:
+  explicit PluginsXmlParser(const std::string& path)
+      : path_(path), doc_ptr_(nullptr) {}
+  ~PluginsXmlParser();
+  bool Parse();
+  const std::vector<std::string>& tags_list();
+  xmlDocPtr doc_ptr();
+
+ private:
+  const std::string path_;
+  xmlDocPtr doc_ptr_;
+  std::vector<std::string> tags_;
+  int NextChildElement(xmlTextReaderPtr reader, int depth);
+
+  class WrapperXMLReader {
+   public:
+    WrapperXMLReader() : reader_(nullptr) {}
+
+    xmlTextReaderPtr Create(const std::string& path) {
+      reader_ = xmlReaderForFile(path.c_str(), nullptr, 0);
+      return reader_;
+    }
+    virtual ~WrapperXMLReader() {
+      if (reader_) {
+        xmlFreeTextReader(reader_);
+      }
+    }
+
+   private:
+    xmlTextReaderPtr reader_;
+  };
+};
+}  // namespace common_installer
+#endif  // COMMON_UTILS_PLUGIN_XML_PARSER_H_