Add factory for actions 27/201327/8
authorJunghoon Park <jh9216.park@samsung.com>
Tue, 12 Mar 2019 10:53:58 +0000 (19:53 +0900)
committermk5004.lee <mk5004.lee@samsung.com>
Thu, 14 Mar 2019 07:01:40 +0000 (16:01 +0900)
Change-Id: I761cfcd8ed680d5683533768ab1b7a59cb9744fb
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
Signed-off-by: mk5004.lee <mk5004.lee@samsung.com>
Signed-off-by: Junghoon Park <jh9216.park@samsung.com>
16 files changed:
notification-ex/abstract_action.cc
notification-ex/abstract_action.h
notification-ex/action_inflator.cc [new file with mode: 0644]
notification-ex/action_inflator.h [new file with mode: 0644]
notification-ex/app_control_action.cc
notification-ex/app_control_action.h
notification-ex/default_action_factory.cc [new file with mode: 0644]
notification-ex/default_action_factory.h [new file with mode: 0644]
notification-ex/default_item_factory.h
notification-ex/factory_manager.cc
notification-ex/factory_manager.h
notification-ex/iaction_factory.h [new file with mode: 0644]
notification-ex/visibility_action.cc
notification-ex/visibility_action.h
unittest/src/test_app_control_action.cc
unittest/src/test_visibility_action.cc

index f6aa0f8..a52414e 100644 (file)
 #endif
 
 #define LOG_TAG "NOTIFICATION_EX"
+#define ABSTRACT_ACTION_TYPE_KEY "__ABSTRACT_ACTION_TYPE_KEY__"
 #define ABSTRACT_ACTION_IS_LOCAL_KEY "__ABSTRACT_ACTION_IS_LOCAL_KEY__"
 #define ABSTRACT_ACTION_EXTRA_KEY "__ABSTRACT_ACTION_EXTRA_KEY__"
 
 namespace notification {
 namespace item {
 AbstractAction::AbstractAction(bool isLocal)
-  : impl_(new Impl(this, isLocal)) {
+    : impl_(new Impl(this, isLocal)) {
 }
 
 AbstractAction::AbstractAction(bool isLocal, std::string extra)
-  : impl_(new Impl(this, isLocal, extra)) {
+    : impl_(new Impl(this, isLocal, extra)) {
 }
 
 AbstractAction::Impl::Impl(AbstractAction* parent, bool isLocal)
-  : parent_(parent) , isLocal_(isLocal) {
+    : parent_(parent) , isLocal_(isLocal) {
   LOGI("Action created");
 }
 
-AbstractAction::Impl::Impl(AbstractAction* parent, bool isLocal, std::string extra)
-  : parent_(parent) , isLocal_(isLocal), extra_(extra) {
+AbstractAction::Impl::Impl(AbstractAction* parent, bool isLocal,
+    std::string extra) : parent_(parent) , isLocal_(isLocal), extra_(extra) {
   LOGI("Action created");
 }
 
 AbstractAction::~AbstractAction() = default;
 AbstractAction::Impl::~Impl() = default;
 
+AbstractAction::Type AbstractAction::GetType(Bundle b) {
+  return static_cast<AbstractAction::Type>(
+      std::stoi(b.GetString(ABSTRACT_ACTION_TYPE_KEY)));
+}
+
 Bundle AbstractAction::Serialize() {
   Bundle b;
 
+  b.Add(ABSTRACT_ACTION_TYPE_KEY, std::to_string(GetType()));
   b.Add(ABSTRACT_ACTION_IS_LOCAL_KEY, std::to_string(impl_->isLocal_));
   if (!impl_->extra_.empty())
     b.Add(ABSTRACT_ACTION_EXTRA_KEY ,impl_->extra_);
index 8a2d9ae..7a6f393 100644 (file)
@@ -32,10 +32,20 @@ namespace item {
 class AbstractItem;
 class EXPORT_API AbstractAction {
  public:
+  enum Type {
+    NullObject,
+    AppControl,
+    Visibility,
+    Custom,
+  };
+
+ public:
   AbstractAction(bool isLocal);
   AbstractAction(bool isLocal, std::string extra);
   virtual ~AbstractAction();
 
+  virtual Type GetType() const = 0;
+  static Type GetType(Bundle b);
   virtual Bundle Serialize() = 0;
   virtual void Deserialize(Bundle b) = 0;
   virtual bool IsLocal() const = 0;
diff --git a/notification-ex/action_inflator.cc b/notification-ex/action_inflator.cc
new file mode 100644 (file)
index 0000000..c757e46
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+
+#include <memory>
+
+#include "notification-ex/factory_manager.h"
+#include "notification-ex/action_inflator.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+
+namespace notification {
+namespace item {
+
+std::shared_ptr<AbstractAction> ActionInflator::Create(Bundle b) {
+  std::shared_ptr<AbstractAction> action =
+      FactoryManager::GetInst().CreateAction(AbstractAction::GetType(b));
+  action.get()->Deserialize(b);
+  return action;
+}
+
+}  // namespace item
+}  // namespace notification
+
diff --git a/notification-ex/action_inflator.h b/notification-ex/action_inflator.h
new file mode 100644 (file)
index 0000000..65329b9
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_ACTION_INFLATOR_H_
+#define NOTIFICATION_EX_ACTION_INFLATOR_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_action.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API ActionInflator {
+ public:
+  static std::shared_ptr<AbstractAction> Create(Bundle b);
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_ACTION_INFLATOR_H_
+
index 5930f52..14ae7e1 100644 (file)
@@ -32,21 +32,21 @@ namespace notification {
 namespace item {
 
 AppControlAction::AppControlAction(app_control_h app_control)
-  : AbstractAction(true), impl_(new Impl(this)) {
+    : AbstractAction(true), impl_(new Impl(this)) {
   app_control_h control_;
   app_control_clone(&control_, app_control);
   impl_->control_ = control_;
 }
 
 AppControlAction::AppControlAction(app_control_h app_control, std::string extra)
-  : AbstractAction(true, extra), impl_(new Impl(this)) {
+    : AbstractAction(true, extra), impl_(new Impl(this)) {
   app_control_h control_;
   app_control_clone(&control_, app_control);
   impl_->control_ = control_;
 }
 
 AppControlAction::Impl::Impl(AppControlAction* parent)
-  : parent_(parent) {
+    : parent_(parent) {
   LOGI("AppControlAction created");
 }
 
@@ -56,6 +56,10 @@ AppControlAction::Impl::~Impl() {
     app_control_destroy(control_);
 }
 
+AbstractAction::Type AppControlAction::GetType() const {
+  return AbstractAction::AppControl;
+}
+
 Bundle AppControlAction::Serialize() {
   Bundle b;
   bundle* control_b = NULL;
index 3a614b7..afd643d 100644 (file)
@@ -30,6 +30,7 @@ class EXPORT_API AppControlAction : public AbstractAction {
   AppControlAction(app_control_h app_control, std::string extra);
   virtual ~AppControlAction();
 
+  AbstractAction::Type GetType() const override;
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
   bool IsLocal() const override;
diff --git a/notification-ex/default_action_factory.cc b/notification-ex/default_action_factory.cc
new file mode 100644 (file)
index 0000000..acaefe3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+
+#include <memory>
+
+#include "notification-ex/app_control_action.h"
+#include "notification-ex/visibility_action.h"
+#include "notification-ex/default_action_factory.h"
+#include "notification-ex/exception.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+unique_ptr<AbstractAction> DefaultActionFactory::CreateAction(
+    AbstractAction::Type type) {
+
+  switch (type) {
+  case AbstractAction::NullObject :
+    THROW(NOTIFICATION_ERROR_INVALID_PARAMETER);
+  case AbstractAction::AppControl :
+    app_control_h control;
+    app_control_create(&control);
+    return unique_ptr<AbstractAction>(new AppControlAction(control));
+  case AbstractAction::Visibility :
+    return unique_ptr<AbstractAction>(new VisibilityAction());
+  case AbstractAction::Custom :
+    return nullptr;
+  }
+
+  return nullptr;
+}
+
+}  // namespace item
+}  // namespace notification
diff --git a/notification-ex/default_action_factory.h b/notification-ex/default_action_factory.h
new file mode 100644 (file)
index 0000000..5381d1f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_DEFAULT_ACTION_FACTORY_H_
+#define NOTIFICATION_EX_DEFAULT_ACTION_FACTORY_H_
+
+#include <memory>
+
+#include "notification-ex/iaction_factory.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API DefaultActionFactory : public IActionFactory {
+ public:
+  virtual ~DefaultActionFactory() = default;
+  std::unique_ptr<AbstractAction> CreateAction(
+      AbstractAction::Type type) override;
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_DEFAULT_ACTION_FACTORY_H_
index 489bd40..7f2b879 100644 (file)
@@ -27,7 +27,7 @@ namespace item {
 class EXPORT_API DefaultItemFactory : public IItemFactory {
  public:
   virtual ~DefaultItemFactory() = default;
-  std::unique_ptr<AbstractItem> CreateItem(AbstractItem::Type type);
+  std::unique_ptr<AbstractItem> CreateItem(AbstractItem::Type type) override;
 };
 
 }  // namespace item
index 19df26f..81e8325 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "notification-ex/factory_manager.h"
 #include "notification-ex/default_item_factory.h"
+#include "notification-ex/default_action_factory.h"
 #include "notification-ex/null_item.h"
 
 #ifdef LOG_TAG
@@ -37,15 +38,27 @@ FactoryManager& FactoryManager::GetInst() {
 }
 
 void FactoryManager::RegisterFactory(std::unique_ptr<IItemFactory> factory) {
-  factory_ = std::move(factory);
+  item_factory_ = std::move(factory);
+}
+
+void FactoryManager::RegisterFactory(std::unique_ptr<IActionFactory> factory) {
+  action_factory_ = std::move(factory);
 }
 
 std::unique_ptr<AbstractItem> FactoryManager::CreateItem(
     AbstractItem::Type type) {
-  if (factory_.get() == nullptr)
-    factory_.reset(new DefaultItemFactory());
+  if (item_factory_.get() == nullptr)
+    item_factory_.reset(new DefaultItemFactory());
+
+  return item_factory_->CreateItem(type);
+}
+
+std::unique_ptr<AbstractAction> FactoryManager::CreateAction(
+    AbstractAction::Type type) {
+  if (action_factory_.get() == nullptr)
+    action_factory_.reset(new DefaultActionFactory());
 
-  return factory_->CreateItem(type);
+  return action_factory_->CreateAction(type);
 }
 
 AbstractItem& FactoryManager::GetNullItem() {
index e203000..55a6e6e 100644 (file)
@@ -22,6 +22,7 @@
 #include <list>
 
 #include "notification-ex/iitem_factory.h"
+#include "notification-ex/iaction_factory.h"
 
 namespace notification {
 namespace item {
@@ -30,14 +31,17 @@ class EXPORT_API FactoryManager {
  public:
   static FactoryManager& GetInst();
   void RegisterFactory(std::unique_ptr<IItemFactory> factory);
+  void RegisterFactory(std::unique_ptr<IActionFactory> factory);
   std::unique_ptr<AbstractItem> CreateItem(AbstractItem::Type type);
+  std::unique_ptr<AbstractAction> CreateAction(AbstractAction::Type type);
   AbstractItem& GetNullItem();
 
  private:
   FactoryManager() {}
 
  private:
-  std::unique_ptr<IItemFactory> factory_;
+  std::unique_ptr<IItemFactory> item_factory_;
+  std::unique_ptr<IActionFactory> action_factory_;
 };
 
 }  // namespace item
diff --git a/notification-ex/iaction_factory.h b/notification-ex/iaction_factory.h
new file mode 100644 (file)
index 0000000..c2d5d81
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_IACTION_FACTORY_H_
+#define NOTIFICATION_EX_IACTION_FACTORY_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_action.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API IActionFactory {
+ public:
+  virtual ~IActionFactory() = default;
+  virtual std::unique_ptr<AbstractAction> CreateAction(
+      AbstractAction::Type type) = 0;
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_IACTION_FACTORY_H_
index 3a8b3df..99fba84 100644 (file)
@@ -31,21 +31,24 @@ namespace notification {
 namespace item {
 
 VisibilityAction::VisibilityAction()
-  : AbstractAction(true), impl_(new Impl(this)) {
+    : AbstractAction(true), impl_(new Impl(this)) {
 }
 
 VisibilityAction::VisibilityAction(std::string extra)
-  : AbstractAction(true, extra), impl_(new Impl(this)) {
+    : AbstractAction(true, extra), impl_(new Impl(this)) {
 }
 
-VisibilityAction::Impl::Impl(VisibilityAction* parent)
-  : parent_(parent) {
+VisibilityAction::Impl::Impl(VisibilityAction* parent) : parent_(parent) {
   LOGI("VisibilityAction created");
 }
 
 VisibilityAction::~VisibilityAction() = default;
 VisibilityAction::Impl::~Impl() = default;
 
+AbstractAction::Type VisibilityAction::GetType() const {
+  return AbstractAction::Visibility;
+}
+
 Bundle VisibilityAction::Serialize() {
   char buf_key[128];
   char buf_data[128];
@@ -123,8 +126,8 @@ std::string VisibilityAction::GetExtra() const {
 }
 
 void VisibilityAction::SetVisibility(std::string id, bool visible) {
-  impl_->entities_.emplace_back(new VisibilityAction::Impl::VisibilityEntity(id,
-    visible));
+  impl_->entities_.emplace_back(new VisibilityAction::Impl::VisibilityEntity(
+      id, visible));
 }
 
 } //namespace item
index 7c0f6e2..d18f52e 100644 (file)
@@ -28,6 +28,7 @@ class EXPORT_API VisibilityAction  : public AbstractAction {
   VisibilityAction(std::string extra);
   virtual ~VisibilityAction();
 
+  AbstractAction::Type GetType() const override;
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
   bool IsLocal() const override;
index e0371e4..e2d4c85 100644 (file)
@@ -18,6 +18,7 @@
 #include <gmock/gmock.h>
 
 #include "notification-ex/app_control_action.h"
+#include "notification-ex/action_inflator.h"
 
 using namespace notification;
 using namespace notification::item;
@@ -27,12 +28,13 @@ class AppControlActionTest : public ::testing::Test {
   AppControlAction* action;
   app_control_h app_control;
   const char* app_id = "test_appid";
+  std::string extra = "appcontrol_extra";
 
   virtual void SetUp() {
     app_control_create(&app_control);
     app_control_set_app_id(app_control, app_id);
 
-    action = new AppControlAction(app_control);
+    action = new AppControlAction(app_control, extra);
   }
   virtual void TearDown() {
     delete action;
@@ -48,28 +50,48 @@ TEST_F(AppControlActionTest, IsLocal) {
   ASSERT_EQ(AppControlActionTest::action->IsLocal(), 1);
 }
 
+TEST_F(AppControlActionTest, GetExtra) {
+  ASSERT_EQ(AppControlActionTest::action->GetExtra(),
+    AppControlActionTest::extra);
+}
+
 TEST_F(AppControlActionTest, SerializeDeserialize) {
   char* app_id = NULL;
 
   Bundle b = AppControlActionTest::action->Serialize();
-  AppControlActionTest::action->Deserialize(b);
 
-  app_control_get_app_id(AppControlActionTest::action->GetAppControl(), &app_id);
-  ASSERT_STREQ(AppControlActionTest::app_id, app_id);
+  std::shared_ptr<AbstractAction> gen_action = ActionInflator::Create(b);
+  ASSERT_EQ(gen_action->GetType(), AbstractAction::AppControl);
+
+  AppControlAction* gen_appcontrol_action =
+    static_cast<AppControlAction*>(gen_action.get());
+
+  app_control_get_app_id(gen_appcontrol_action->GetAppControl(), &app_id);
+  ASSERT_STREQ(app_id, AppControlActionTest::app_id);
+
+  if (app_id)
+    free(app_id);
 }
 
 TEST_F(AppControlActionTest, AppControl) {
+  app_control_h app_control;
   const char* app_id = "new_appid";
   char* app_id_ = NULL;
-  app_control_h app_control;
-  app_control_h app_control_;
 
   app_control_create(&app_control);
   app_control_set_app_id(app_control, app_id);
-
   AppControlActionTest::action->SetAppControl(app_control);
-  app_control_ = AppControlActionTest::action->GetAppControl();
-  app_control_get_app_id(app_control_, &app_id_);
+  app_control_destroy(app_control);
+
+  Bundle b = AppControlActionTest::action->Serialize();
+
+  std::shared_ptr<AbstractAction> gen_action = ActionInflator::Create(b);
+  AppControlAction* gen_appcontrol_action =
+    static_cast<AppControlAction*>(gen_action.get());
 
+  app_control_get_app_id(gen_appcontrol_action->GetAppControl(), &app_id_);
   EXPECT_STREQ(app_id, app_id_);
+
+  if (app_id_)
+    free(app_id_);
 }
index 0795a47..4716460 100644 (file)
@@ -20,6 +20,7 @@
 #include <gmock/gmock.h>
 
 #include "notification-ex/visibility_action.h"
+#include "notification-ex/action_inflator.h"
 
 using namespace notification;
 using namespace notification::item;
@@ -28,10 +29,11 @@ class VisibilityActionTest : public ::testing::Test {
  public:
   VisibilityAction* visibility;
   std::string id = "visibility_id";
+  std::string extra = "visibility_extra";
   bool visible = true;
 
   virtual void SetUp() {
-    visibility = new VisibilityAction();
+    visibility = new VisibilityAction(extra);
     visibility->SetVisibility("visibility_id", visible);
   }
   virtual void TearDown() {
@@ -47,11 +49,34 @@ TEST_F(VisibilityActionTest, IsLocal) {
   ASSERT_EQ(VisibilityActionTest::visibility->IsLocal(), 1);
 }
 
+TEST_F(VisibilityActionTest, GetExtra) {
+  ASSERT_EQ(VisibilityActionTest::visibility->GetExtra(),
+    VisibilityActionTest::extra);
+}
+
 TEST_F(VisibilityActionTest, SerializeDeserialize) {
   Bundle b = VisibilityActionTest::visibility->Serialize();
-  VisibilityActionTest::visibility->Deserialize(b);
+
+  std::shared_ptr<AbstractAction> gen_action = ActionInflator::Create(b);
+  ASSERT_EQ(gen_action->GetType(), AbstractAction::Visibility);
+
+  VisibilityAction* gen_visibility_action =
+    static_cast<VisibilityAction*>(gen_action.get());
+  EXPECT_NE(gen_visibility_action, nullptr);
+  ASSERT_EQ(gen_visibility_action->IsLocal(), true);
+  ASSERT_EQ(gen_visibility_action->GetExtra(), VisibilityActionTest::extra);
 }
 
 TEST_F(VisibilityActionTest, SetVisibility) {
   VisibilityActionTest::visibility->SetVisibility("test_id", true);
+  Bundle b = VisibilityActionTest::visibility->Serialize();
+
+  std::shared_ptr<AbstractAction> gen_action = ActionInflator::Create(b);
+  ASSERT_EQ(gen_action->GetType(), AbstractAction::Visibility);
+
+  VisibilityAction* gen_visibility_action =
+    static_cast<VisibilityAction*>(gen_action.get());
+  EXPECT_NE(gen_visibility_action, nullptr);
+  ASSERT_EQ(gen_visibility_action->IsLocal(), true);
+  ASSERT_EQ(gen_visibility_action->GetExtra(), VisibilityActionTest::extra);
 }