Add StepConvertXml for tpk backend 07/54607/4 accepted/tizen/mobile/20151217.223533 accepted/tizen/tv/20151217.223547 accepted/tizen/wearable/20151217.223602 submit/tizen/20151217.070232
authorSangyoon Jang <s89.jang@samsung.com>
Wed, 16 Dec 2015 11:58:50 +0000 (20:58 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Thu, 17 Dec 2015 06:16:24 +0000 (22:16 -0800)
StepConvertXml copies tpk packages manifest file with some modification.
replace StepGenerateXml with StepConvertXml in tpk-backend.

current manifest generation cannot generate some elements/attributes for
plugin-parsers, because manifest-parser and app-installer don't handle
all of elements/attributes.

Change-Id: I743050a47d4b21150a82a760e7717ced97fa4886
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
src/tpk/CMakeLists.txt
src/tpk/step/step_convert_xml.cc [new file with mode: 0644]
src/tpk/step/step_convert_xml.h [new file with mode: 0644]
src/tpk/tpk_installer.cc

index 856ddac..7301962 100644 (file)
@@ -3,6 +3,7 @@ SET(SRCS
     step/step_create_symbolic_link.cc
     step/step_parse.cc
     step/step_parse_recovery.cc
+    step/step_convert_xml.cc
     tpk_app_query_interface.cc
     tpk_installer.cc
 )
diff --git a/src/tpk/step/step_convert_xml.cc b/src/tpk/step/step_convert_xml.cc
new file mode 100644 (file)
index 0000000..6051901
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (c) 2015 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 "tpk/step/step_convert_xml.h"
+
+#include <pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/system/error_code.hpp>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+
+#include <string>
+
+#include "common/utils/glist_range.h"
+
+namespace bs = boost::system;
+namespace bf = boost::filesystem;
+
+namespace {
+
+const xmlChar kExecAttributeKey[] = "exec";
+const xmlChar kXmlNamespaceUri[] = "http://tizen.org/ns/packages";
+const char kXmlXPathAppExpr[] =
+    "//*[local-name()='ui-application' or local-name()='service-application' "
+    "or local-name()='widget-application']";
+
+}  // namespace
+
+namespace common_installer {
+namespace tpk {
+
+Step::Status StepConvertXml::precheck() {
+  bf::path xml_path = context_->pkg_path.get();
+  xml_path /= "tizen-manifest.xml";
+
+  if (!bf::exists(xml_path)) {
+    LOG(ERROR) << "Cannot find manifest file";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  xml_path_ = xml_path;
+
+  return Step::Status::OK;
+}
+
+bool StepConvertXml::ConvertXml(xmlDocPtr doc) {
+  xmlXPathContextPtr xpath_ctx;
+
+  xpath_ctx = xmlXPathNewContext(doc);
+  if (!xpath_ctx) {
+    LOG(ERROR) << "Failed to create XPath context";
+    return false;
+  }
+
+  for (application_x* app :
+       GListRange<application_x*>(context_->manifest_data.get()->application)) {
+    std::string expr;
+    xmlXPathObjectPtr xpath_obj;
+    xmlNodePtr node;
+
+    expr = std::string(kXmlXPathAppExpr) + "[@appid='" + app->appid + "']";
+    xpath_obj = xmlXPathEvalExpression((const xmlChar*)expr.c_str(), xpath_ctx);
+    if (!xpath_obj || !xpath_obj->nodesetval || !xpath_obj->nodesetval->nodeNr)
+      continue;
+
+    node = xpath_obj->nodesetval->nodeTab[0];
+    xmlSetProp(node, kExecAttributeKey, (const xmlChar*)app->exec);
+    xmlXPathFreeObject(xpath_obj);
+  }
+
+  xmlXPathFreeContext(xpath_ctx);
+
+  return true;
+}
+
+Step::Status StepConvertXml::process() {
+  xmlDocPtr doc = xmlParseFile(xml_path_.string().c_str());
+  if (!doc) {
+    LOG(ERROR) << "Failed to parse xml file";
+    return Step::Status::ERROR;
+  }
+
+  if (!ConvertXml(doc))
+    return Step::Status::ERROR;
+
+  bf::path new_path = bf::path(getUserManifestPath(context_->uid.get()))
+      / bf::path(context_->pkgid.get());
+  new_path += ".xml";
+  if (xmlSaveFile(new_path.string().c_str(), doc) == -1) {
+    LOG(ERROR) << "Failed to write xml file";
+    return Step::Status::ERROR;
+  }
+
+  context_->xml_path.set(new_path.string());
+
+  if (pkgmgr_parser_check_manifest_validation(
+      context_->xml_path.get().c_str()) != 0) {
+    LOG(ERROR) << "Manifest is not valid";
+    return Step::Status::ERROR;
+  }
+
+  LOG(DEBUG) << "Successfully create manifest xml "
+      << context_->xml_path.get();
+
+  return Step::Status::OK;
+}
+
+Step::Status StepConvertXml::clean() {
+  return Step::Status::OK;
+}
+
+Step::Status StepConvertXml::undo() {
+  bs::error_code error;
+
+  if (bf::exists(context_->xml_path.get()))
+    bf::remove_all(context_->xml_path.get(), error);
+
+  return Step::Status::OK;
+}
+
+}  // namespace tpk
+}  // namespace common_installer
diff --git a/src/tpk/step/step_convert_xml.h b/src/tpk/step/step_convert_xml.h
new file mode 100644 (file)
index 0000000..9f129fb
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2015 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 TPK_STEP_STEP_CONVERT_XML_H_
+#define TPK_STEP_STEP_CONVERT_XML_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include <boost/filesystem/path.hpp>
+#include <libxml/tree.h>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace tpk {
+
+class StepConvertXml : public common_installer::Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override;
+  Status undo() override;
+  Status precheck() override;
+
+ private:
+  boost::filesystem::path xml_path_;
+  bool ConvertXml(xmlDocPtr doc);
+
+  SCOPE_LOG_TAG(ConvertXml)
+};
+
+}  // namespace tpk
+}  // namespace common_installer
+
+#endif  // TPK_STEP_STEP_CONVERT_XML_H_
index 2cb4a64..34779b3 100644 (file)
@@ -42,6 +42,7 @@
 #include "tpk/step/step_create_symbolic_link.h"
 #include "tpk/step/step_parse.h"
 #include "tpk/step/step_parse_recovery.h"
+#include "tpk/step/step_convert_xml.h"
 
 namespace ci = common_installer;
 
@@ -107,7 +108,7 @@ void TpkInstaller::InstallSteps() {
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
   AddStep<ci::filesystem::StepCreateIcons>();
   AddStep<ci::security::StepRegisterSecurity>();
-  AddStep<ci::pkgmgr::StepGenerateXml>();
+  AddStep<ci::tpk::StepConvertXml>();
   AddStep<ci::pkgmgr::StepRegisterApplication>();
 }
 
@@ -130,7 +131,7 @@ void TpkInstaller::UpdateSteps() {
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
   AddStep<ci::filesystem::StepCreateIcons>();
   AddStep<ci::security::StepUpdateSecurity>();
-  AddStep<ci::pkgmgr::StepGenerateXml>();
+  AddStep<ci::tpk::StepConvertXml>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
   /* TODO(jungh.yeon): this temporary step will be removed
   * when secondary parsing procedure has removed*/
@@ -172,7 +173,7 @@ void TpkInstaller::DeltaSteps() {
   AddStep<tpk::filesystem::StepCreateSymbolicLink>();
   AddStep<ci::filesystem::StepCreateIcons>();
   AddStep<ci::security::StepUpdateSecurity>();
-  AddStep<ci::pkgmgr::StepGenerateXml>();
+  AddStep<ci::tpk::StepConvertXml>();
   AddStep<ci::pkgmgr::StepUpdateApplication>();
 }