Add IME parser's handlers 20/34920/7
authorTomasz Iwanek <t.iwanek@samsung.com>
Mon, 2 Feb 2015 12:31:00 +0000 (13:31 +0100)
committerPawel Sikorski <p.sikorski@samsung.com>
Wed, 18 Feb 2015 13:43:52 +0000 (05:43 -0800)
Change-Id: I8b316d4ce04f05397e05903cd3a921cd05013637

src/widget-manifest-parser/CMakeLists.txt
src/widget-manifest-parser/manifest_handler.cc
src/widget-manifest-parser/manifest_handlers/category_handler.cc [new file with mode: 0644]
src/widget-manifest-parser/manifest_handlers/category_handler.h [new file with mode: 0644]
src/widget-manifest-parser/manifest_handlers/ime_handler.cc [new file with mode: 0644]
src/widget-manifest-parser/manifest_handlers/ime_handler.h [new file with mode: 0644]

index 33bd14e..32b506b 100644 (file)
@@ -4,6 +4,8 @@ SET(SRCS
   application_manifest_constants.cc
   manifest.cc
   manifest_handler.cc
+  manifest_handlers/category_handler.cc
+  manifest_handlers/ime_handler.cc
   manifest_handlers/permissions_handler.cc
   manifest_handlers/tizen_application_handler.cc
   manifest_handlers/widget_handler.cc
index fd49689..6d0fd91 100644 (file)
 #include "widget-manifest-parser/application_manifest_constants.h"
 
 #include "widget-manifest-parser/manifest_handlers/permissions_handler.h"
+#include "widget-manifest-parser/manifest_handlers/category_handler.h"
+#include "widget-manifest-parser/manifest_handlers/ime_handler.h"
 #include "widget-manifest-parser/manifest_handlers/tizen_application_handler.h"
 #include "widget-manifest-parser/manifest_handlers/widget_handler.h"
 
 // TODO(t.iwanek): add following handlers
 // #include "widget-manifest-parser/manifest_handlers/tizen_appwidget_handler.h"
-// #include "widget-manifest-parser/manifest_handlers/tizen_category_handler.h"
-// #include "widget-manifest-parser/manifest_handlers/tizen_ime_handler.h"
 // #include "widget-manifest-parser/manifest_handlers/tizen_metadata_handler.h"
 // #include "widget-manifest-parser/manifest_handlers/tizen_navigation_handler.h"
 // #include "widget-manifest-parser/manifest_handlers/tizen_setting_handler.h"
@@ -34,25 +34,22 @@ bool ValidateImeCategory(
     std::string* error) {
   namespace keys = common_installer::application_widget_keys;
   // if config contains tizen:ime tag, proper category should be specified
-
-   // TODO(t.iwanek): fix me - add IME handler and uncomment
-
-//  if (application.GetManifestData(keys::kTizenImeKey)) {
-//    const common_installer::widget_manifest_parser::CategoryInfoList*
-//        categories_list =
-//            static_cast<const CategoryInfoList*>(
-//                application.GetManifestData(keys::kTizenCategoryKey));
-
-//    if (categories_list) {
-//      const char imeCategory[] = "http://tizen.org/category/ime";
-//      for (const std::string& category : categories_list->categories) {
-//        if (category == imeCategory)
-//          return true;
-//      }
-//    }
-//    *error = "tizen:ime is specified but not proper category added";
-//    return false;
-//  }
+  if (application.GetManifestData(keys::kTizenImeKey)) {
+    const common_installer::widget_manifest_parser::CategoryInfoList*
+        categories_list =
+            static_cast<const CategoryInfoList*>(
+                application.GetManifestData(keys::kTizenCategoryKey));
+
+    if (categories_list) {
+      const char imeCategory[] = "http://tizen.org/category/ime";
+      for (const std::string& category : categories_list->categories) {
+        if (category == imeCategory)
+          return true;
+      }
+    }
+    *error = "tizen:ime is specified but not proper category added";
+    return false;
+  }
   return true;
 }
 
@@ -109,6 +106,8 @@ ManifestHandlerRegistry::GetInstanceForWGT() {
   handlers.push_back(new WidgetHandler);
   handlers.push_back(new TizenApplicationHandler);
   handlers.push_back(new PermissionsHandler);
+  handlers.push_back(new CategoryHandler);
+  handlers.push_back(new ImeHandler);
 
   widget_registry_ = new ManifestHandlerRegistry(handlers);
   return widget_registry_;
diff --git a/src/widget-manifest-parser/manifest_handlers/category_handler.cc b/src/widget-manifest-parser/manifest_handlers/category_handler.cc
new file mode 100644 (file)
index 0000000..25a65c0
--- /dev/null
@@ -0,0 +1,95 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_handlers/category_handler.h"
+
+#include "utils/values.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+namespace keys = application_widget_keys;
+
+namespace {
+
+const char kErrMsgCategory[] =
+    "Parsing category element failed";
+const char kErrMsgCategoryName[] =
+    "The name element inside category element is obligatory";
+
+bool ParseCategoryEntryAndStore(const utils::DictionaryValue& control_dict,
+    CategoryInfoList* aplist) {
+  std::string name;
+  if (!control_dict.GetString(keys::kTizenCategoryNameKey, &name))
+    return false;
+  aplist->categories.push_back(name);
+  return true;
+}
+
+}  // namespace
+
+CategoryHandler::CategoryHandler() {
+}
+
+CategoryHandler::~CategoryHandler() {
+}
+
+bool CategoryHandler::Parse(std::shared_ptr<ApplicationData> application,
+    std::string* error) {
+  const Manifest* manifest = application->GetManifest();
+  std::shared_ptr<CategoryInfoList> aplist(new CategoryInfoList());
+  utils::Value* value;
+  manifest->Get(keys::kTizenCategoryKey, &value);
+
+  if (value->GetType() == utils::Value::TYPE_LIST) {
+    // multiple entries
+    const utils::ListValue* list;
+    value->GetAsList(&list);
+    for (const auto& item : *list) {
+      const utils::DictionaryValue* control_dict;
+      if (!item->GetAsDictionary(&control_dict) ||
+          !ParseCategoryEntryAndStore(*control_dict, aplist.get())) {
+        *error = kErrMsgCategory;
+        return false;
+      }
+    }
+  } else if (value->GetType() == utils::Value::TYPE_DICTIONARY) {
+    // single entry
+    const utils::DictionaryValue* dict;
+    value->GetAsDictionary(&dict);
+    if (!ParseCategoryEntryAndStore(*dict, aplist.get()))
+      return false;
+  } else {
+    *error = kErrMsgCategory;
+    return false;
+  }
+
+  application->SetManifestData(keys::kTizenCategoryKey, aplist);
+  return true;
+}
+
+bool CategoryHandler::Validate(
+    std::shared_ptr<const ApplicationData> application,
+    std::string* error) const {
+  const CategoryInfoList* categories_list =
+      static_cast<const CategoryInfoList*>(
+          application->GetManifestData(keys::kTizenCategoryKey));
+
+  for (const auto& item : categories_list->categories) {
+    if (item.empty()) {
+      *error = kErrMsgCategoryName;
+      return false;
+    }
+  }
+  return true;
+}
+
+std::vector<std::string> CategoryHandler::Keys() const {
+  return std::vector<std::string>(1, keys::kTizenCategoryKey);
+}
+
+}  // namespace widget_manifest_parser
+}  // namespace common_installer
diff --git a/src/widget-manifest-parser/manifest_handlers/category_handler.h b/src/widget-manifest-parser/manifest_handlers/category_handler.h
new file mode 100644 (file)
index 0000000..96dcae6
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_CATEGORY_HANDLER_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_CATEGORY_HANDLER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "utils/macros.h"
+#include "widget-manifest-parser/application_data.h"
+#include "widget-manifest-parser/manifest_handler.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+struct CategoryInfoList : public ApplicationData::ManifestData {
+  std::vector<std::string> categories;
+};
+
+class CategoryHandler : public ManifestHandler {
+ public:
+  CategoryHandler();
+  virtual ~CategoryHandler();
+  bool Parse(std::shared_ptr<ApplicationData> application,
+      std::string* error) override;
+  bool Validate(std::shared_ptr<const ApplicationData> application,
+      std::string* error) const override;
+  std::vector<std::string> Keys() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CategoryHandler);
+};
+
+}  // namespace widget_manifest_parser
+}  // namespace common_installer
+
+#endif  // WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_CATEGORY_HANDLER_H_
diff --git a/src/widget-manifest-parser/manifest_handlers/ime_handler.cc b/src/widget-manifest-parser/manifest_handlers/ime_handler.cc
new file mode 100644 (file)
index 0000000..f15cb61
--- /dev/null
@@ -0,0 +1,177 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#include "widget-manifest-parser/manifest_handlers/ime_handler.h"
+
+#include <cassert>
+#include <memory>
+#include <regex>
+
+#include "utils/values.h"
+#include "widget-manifest-parser/application_manifest_constants.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+namespace keys = application_widget_keys;
+
+namespace {
+
+const char kErrMsgLanguages[] =
+    "At least and only ONE tizen:languages tag should be specified";
+const char kErrMsgEmptyLanguage[] =
+    "Language cannot be empty";
+const char kErrMsgParsingIme[] =
+    "Only one ime tag should be specified";
+const char kErrMsgParsingUuid[] =
+    "Only one uuid tag should be specified";
+const char kErrMsgValidatingUuidEmpty[] =
+    "The UUID of ime element is obligatory";
+const char kErrMsgUuidFormat[] =
+    "Uuid should be in proper format (8-4-4-4-12)";
+const char kErrMsgNoLanguages[] =
+    "At least one language of ime element should be specified";
+
+const std::regex kUuidRegex(
+    "^[0-9a-zA-Z]{8}([-][0-9a-zA-Z]{4}){3}[-][0-9a-zA-Z]{12}$");
+
+bool GetLanguage(const utils::Value* item, ImeInfo* ime_info,
+    std::string* error) {
+  const utils::DictionaryValue* language_dict;
+  if (item->GetAsDictionary(&language_dict)) {
+    std::string language;
+    if (!language_dict->GetString(keys::kTizenImeLanguageTextKey, &language) ||
+        language.empty()) {
+      *error = kErrMsgEmptyLanguage;
+      return false;
+    }
+    ime_info->AddLanguage(language);
+  }
+  return true;
+}
+
+bool ParseImeEntryAndStore(const utils::DictionaryValue& control_dict,
+    ImeInfo* ime_info, std::string* error) {
+
+  // parsing uuid element
+  const utils::DictionaryValue* uuid_dict;
+  std::string uuid;
+  if (control_dict.GetDictionary(keys::kTizenImeUuidKey, &uuid_dict) &&
+      uuid_dict->GetString(keys::kTizenImeUuidTextKey, &uuid)) {
+    ime_info->set_uuid(uuid);
+  } else {
+    *error = kErrMsgParsingUuid;
+    return false;
+  }
+
+  const utils::DictionaryValue* languages_dict;
+  if (!control_dict.GetDictionary(
+      keys::kTizenImeLanguagesKey, &languages_dict)) {
+    *error = kErrMsgLanguages;
+    return false;
+  }
+
+  const utils::Value* languages;
+  if (!languages_dict->Get(keys::kTizenImeLanguageKey, &languages)) {
+    *error = kErrMsgNoLanguages;
+    return false;
+  }
+
+  if (languages->GetType() == utils::Value::TYPE_LIST) {
+    // many languages
+    const utils::ListValue* list;
+    languages->GetAsList(&list);
+    for (const auto& item : *list) {
+      if (!GetLanguage(item, ime_info, error))
+        return false;
+    }
+  } else if (languages->GetType() == utils::Value::TYPE_DICTIONARY) {
+    if (!GetLanguage(languages, ime_info, error))
+      return false;
+  }
+
+  return true;
+}
+
+// UUID is string of 36 characters in form 8-4-4-4-12
+bool IsValidUuid(const std::string& uuid) {
+  return std::regex_match(uuid, kUuidRegex);
+}
+
+}  // namespace
+
+ImeInfo::ImeInfo() {
+}
+
+ImeInfo::~ImeInfo() {
+}
+
+ImeHandler::ImeHandler() {
+}
+
+ImeHandler::~ImeHandler() {
+}
+
+void ImeInfo::AddLanguage(const std::string& language) {
+  languages_.push_back(language);
+}
+
+bool ImeHandler::Parse(std::shared_ptr<ApplicationData> application,
+    std::string* error) {
+  std::shared_ptr<ImeInfo> ime_info(new ImeInfo);
+  const Manifest* manifest = application->GetManifest();
+  assert(manifest);
+
+  utils::Value* value;
+  manifest->Get(keys::kTizenImeKey, &value);
+
+  bool result = true;
+
+  if (value->GetType() == utils::Value::TYPE_DICTIONARY) {
+    // single entry
+    const utils::DictionaryValue* dict;
+    value->GetAsDictionary(&dict);
+    result = ParseImeEntryAndStore(*dict, ime_info.get(), error);
+  } else {
+    *error = kErrMsgParsingIme;
+    return false;
+  }
+
+  application->SetManifestData(keys::kTizenImeKey, ime_info);
+  return result;
+}
+
+bool ImeHandler::Validate(
+    std::shared_ptr<const ApplicationData> application,
+    std::string* error) const {
+
+  const ImeInfo* ime_info =
+      static_cast<const ImeInfo*>(
+          application->GetManifestData(keys::kTizenImeKey));
+
+  if (ime_info->uuid().empty()) {
+    *error = kErrMsgValidatingUuidEmpty;
+    return false;
+  }
+
+  if (!IsValidUuid(ime_info->uuid())) {
+    *error = kErrMsgUuidFormat;
+    return false;
+  }
+
+  if (ime_info->languages().empty()) {
+    *error = kErrMsgNoLanguages;
+    return false;
+  }
+
+  return true;
+}
+
+std::vector<std::string> ImeHandler::Keys() const {
+  return std::vector<std::string>(1, keys::kTizenImeKey);
+}
+
+}  // namespace widget_manifest_parser
+}  // namespace common_installer
diff --git a/src/widget-manifest-parser/manifest_handlers/ime_handler.h b/src/widget-manifest-parser/manifest_handlers/ime_handler.h
new file mode 100644 (file)
index 0000000..54d52d1
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE-xwalk file.
+
+#ifndef WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_IME_HANDLER_H_
+#define WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_IME_HANDLER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "utils/macros.h"
+#include "widget-manifest-parser/application_data.h"
+#include "widget-manifest-parser/manifest_handler.h"
+
+namespace common_installer {
+namespace widget_manifest_parser {
+
+class ImeInfo : public ApplicationData::ManifestData {
+ public:
+  ImeInfo();
+  virtual ~ImeInfo();
+
+  const std::string& uuid() const {
+    return uuid_;
+  }
+  void set_uuid(const std::string& uuid) { uuid_ = uuid; }
+  const std::vector<std::string>& languages() const {
+    return languages_;
+  }
+  void AddLanguage(const std::string& language);
+
+ private:
+  std::string uuid_;
+  std::vector<std::string> languages_;
+};
+
+class ImeHandler : public ManifestHandler {
+ public:
+  ImeHandler();
+  virtual ~ImeHandler();
+  bool Parse(std::shared_ptr<ApplicationData> application,
+      std::string* error) override;
+  bool Validate(std::shared_ptr<const ApplicationData> application,
+      std::string* error) const override;
+  std::vector<std::string> Keys() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ImeHandler);
+};
+
+}  // namespace widget_manifest_parser
+}  // namespace common_installer
+
+#endif  // WIDGET_MANIFEST_PARSER_MANIFEST_HANDLERS_IME_HANDLER_H_