Adjust Null Object pattern for FindById 97/200297/5
authorhyunho <hhstark.kang@samsung.com>
Thu, 21 Feb 2019 08:09:39 +0000 (17:09 +0900)
committerhyunho <hhstark.kang@samsung.com>
Thu, 21 Feb 2019 09:02:55 +0000 (18:02 +0900)
Change-Id: I00e3a720dc632e9807c2321d7999bf1b79875425
Signed-off-by: hyunho <hhstark.kang@samsung.com>
13 files changed:
notification-ex/abstract_item.cc
notification-ex/abstract_item.h
notification-ex/button_item.cc
notification-ex/button_item.h
notification-ex/group_item.cc
notification-ex/group_item.h
notification-ex/item.h
notification-ex/item_factory.cc
notification-ex/item_factory.h
notification-ex/null_item.cc [new file with mode: 0644]
notification-ex/null_item.h [new file with mode: 0644]
unittest/src/test_button_item.cc
unittest/src/test_group_item.cc

index 2503d88..e6195e4 100644 (file)
@@ -36,10 +36,6 @@ using namespace std;
 namespace notification {
 namespace item {
 
-AbstractItem::AbstractItem()
-  : impl_(new Impl(this)) {
-}
-
 AbstractItem::AbstractItem(AbstractItem::Type type,
     std::shared_ptr<AbstractAction> action)
   : impl_(new Impl(this, type, action)) {
@@ -62,11 +58,6 @@ AbstractItem::Impl::Impl(AbstractItem* parent,
   LOGI("GroupItem created");
 }
 
-AbstractItem::Impl::Impl(AbstractItem* parent)
-  : parent_(parent) {
-  LOGI("GroupItem created");
-}
-
 AbstractItem::~AbstractItem() = default;
 
 Bundle AbstractItem::Serialize() {
index e63dd04..f9fb084 100644 (file)
@@ -167,6 +167,7 @@ class EXPORT_API LEDInfo {
 class EXPORT_API AbstractItem {
  public:
   enum Type {
+    NullObject,
     Text,
     Image,
     Icon,
@@ -197,7 +198,7 @@ class EXPORT_API AbstractItem {
 
   virtual Bundle Serialize() = 0;
   virtual void Deserialize(Bundle b) = 0;
-  virtual std::shared_ptr<AbstractItem> FindByID(std::string id) = 0;
+  virtual AbstractItem& FindByID(std::string id) = 0;
   std::string GetId() const;
   void SetId(std::string id);
   std::shared_ptr<AbstractAction> GetAction() const;
index 98c2c78..852bb7d 100644 (file)
@@ -19,6 +19,7 @@
 #include <memory>
 
 #include "notification-ex/button_item.h"
+#include "notification-ex/item_factory.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -53,10 +54,10 @@ void ButtonItem::Deserialize(Bundle b) {
   title_ = b.GetString(BUTTON_TITLE_KEY);
 }
 
-shared_ptr<AbstractItem> ButtonItem::FindByID(std::string id) {
+AbstractItem& ButtonItem::FindByID(std::string id) {
   if (GetId() == id)
-    return shared_ptr<AbstractItem>(this);
-  return nullptr;
+    return *this;
+  return ItemFactory::GetNullItem();
 }
 
 std::string ButtonItem::GetTitle() const {
index ae5765f..3282269 100644 (file)
@@ -37,7 +37,7 @@ class EXPORT_API ButtonItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   std::string GetTitle() const;
 
  private:
index 451a018..f3fa086 100644 (file)
@@ -73,8 +73,7 @@ Bundle GroupItem::Serialize() {
     Bundle serialized = i.get()->Serialize();
     serialized.Add(
         GROUP_CHILDREN_TYPE_KEY, to_string((int)i.get()->GetType()));
-    char* str = strdup(reinterpret_cast<char*>(serialized.ToRaw().first.get()));
-    arr.push_back(str);
+    arr.push_back(reinterpret_cast<char*>(serialized.ToRaw().first.get()));
   }
   b.Add(GROUP_CHILDREN_KEY, arr);
 
@@ -103,12 +102,12 @@ void GroupItem::Deserialize(Bundle b) {
   }
 }
 
-shared_ptr<AbstractItem> GroupItem::FindByID(std::string id) {
+AbstractItem& GroupItem::FindByID(std::string id) {
   for (auto& i : impl_->children_list_) {
     if (i.get()->GetId() == id)
-      return i;
+      return *i;
   }
-  return nullptr;
+  return ItemFactory::GetNullItem();
 }
 
 void GroupItem::AddChild(shared_ptr<AbstractItem> child) {
index 319ab57..0a1c379 100644 (file)
@@ -36,7 +36,7 @@ class EXPORT_API GroupItem : public AbstractItem {
  public:
   virtual Bundle Serialize() override;
   virtual void Deserialize(Bundle b) override;
-  virtual std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  virtual AbstractItem& FindByID(std::string id) override;
 
   void SetDirection(bool vertical);
   bool IsVertical();
index 46c4177..1c8bc49 100644 (file)
@@ -40,7 +40,7 @@ class EXPORT_API TextItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   void SetContents(std::string contents);
   std::string GetContents() const;
   std::string GetHyperLink() const;
@@ -56,7 +56,7 @@ class EXPORT_API IconItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
 
  private:
   std::string iconPath_ = nullptr;
@@ -69,7 +69,7 @@ class EXPORT_API IconTextItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   IconItem GetIconItem() const;
   TextItem GetTextItem() const;
 
@@ -85,7 +85,7 @@ class EXPORT_API ImageItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   std::string GetImagePath() const;
 
  private:
@@ -99,7 +99,7 @@ class EXPORT_API ProgressItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   float GetCurrent() const;
   void SetCurrent(float current);
   float GetMin() const;
@@ -118,7 +118,7 @@ class EXPORT_API CheckBoxItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   bool IsChecked() const;
 
 private:
@@ -138,7 +138,7 @@ class EXPORT_API ChatMessageItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   TextItem GetTextItem() const;
   TextItem GetDataItem() const;
   time_t GetTimeItem() const;
@@ -152,7 +152,7 @@ class EXPORT_API InputSelectorItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   std::list<std::string> GetContents() const;
   void SetContents(std::list<std::string> contents);
 
@@ -167,7 +167,7 @@ class EXPORT_API EntryItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   std::string GetText() const;
   void SetText(std::string text);
   void SetTextLimit(int size);
@@ -185,7 +185,7 @@ class EXPORT_API EffectItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
   std::string GetSoundPath() const;
   std::string GetVibrationPath() const;
 
@@ -201,7 +201,7 @@ class EXPORT_API CustomItem : public AbstractItem {
 
   Bundle Serialize() override;
   void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  AbstractItem& FindByID(std::string id) override;
 };  // class CustomItem
 
 }  // namespace item
index 464bce7..b8aab47 100644 (file)
@@ -21,6 +21,8 @@
 #include "notification-ex/item_factory.h"
 #include "notification-ex/button_item.h"
 #include "notification-ex/group_item.h"
+#include "notification-ex/null_item.h"
+#include "notification-ex/exception.h"
 
 #ifdef LOG_TAG
 #undef LOG_TAG
@@ -34,6 +36,8 @@ namespace item {
 
 shared_ptr<AbstractItem> ItemFactory::CreateItem(AbstractItem::Type type) {
   switch (type) {
+  case AbstractItem::NullObject :
+    THROW(NOTIFICATION_ERROR_INVALID_PARAMETER);
   case AbstractItem::Text :
     return make_shared<ButtonItem>("");
   case AbstractItem::Icon :
@@ -62,6 +66,10 @@ shared_ptr<AbstractItem> ItemFactory::CreateItem(AbstractItem::Type type) {
 
   return nullptr;
 }
+AbstractItem& ItemFactory::GetNullItem() {
+  static NullItem item;
+  return item;
+}
 
 }  // namespace item
 }  // namespace notification
index e28d912..ec24324 100644 (file)
@@ -29,6 +29,7 @@ namespace item {
 class EXPORT_API ItemFactory {
  public:
   std::shared_ptr<AbstractItem> CreateItem(AbstractItem::Type type);
+  static AbstractItem& GetNullItem();
 };
 
 }  // namespace item
diff --git a/notification-ex/null_item.cc b/notification-ex/null_item.cc
new file mode 100644 (file)
index 0000000..a1119c0
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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/null_item.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+NullItem::NullItem(shared_ptr<AbstractAction> action)
+  : AbstractItem(AbstractItem::NullObject, action) {
+}
+
+NullItem::NullItem(string id,
+      shared_ptr<AbstractAction> action)
+  : AbstractItem(id, AbstractItem::NullObject, action) {
+}
+NullItem::~NullItem() = default;
+
+Bundle NullItem::Serialize() {
+  Bundle b;
+  b = AbstractItem::Serialize();
+  return b;
+}
+
+void NullItem::Deserialize(Bundle b) {
+  AbstractItem::Deserialize(b);
+}
+
+AbstractItem& NullItem::FindByID(std::string id) {
+  return *this;
+}
+
+}  // namespace item
+}  // namespace notification
diff --git a/notification-ex/null_item.h b/notification-ex/null_item.h
new file mode 100644 (file)
index 0000000..15d28e0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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_NULL_ITEM_H_
+#define NOTIFICATION_EX_NULL_ITEM_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_item.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API NullItem : public AbstractItem {
+ public:
+  NullItem(std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  NullItem(std::string id,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  virtual ~NullItem();
+
+ public:
+  virtual Bundle Serialize() override;
+  virtual void Deserialize(Bundle b) override;
+  virtual AbstractItem& FindByID(std::string id) override;
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_NULL_ITEM_H_
index 7a4ac00..167aa95 100644 (file)
@@ -18,6 +18,22 @@ class ButtonItemTest : public ::testing::Test {
   void TearDown() override {}
 };
 
+
+TEST_F(ButtonItemTest, FindByID) {
+  ButtonItem item("btn_id", "title");
+
+  AbstractItem& child = item.FindByID("btn_id");
+  ButtonItem& btn = static_cast<ButtonItem&>(child);
+  ASSERT_EQ(btn.GetTitle(), "title");
+}
+
+TEST_F(ButtonItemTest, FindByIDNullItemReturn) {
+  ButtonItem item("btn_id", "title");
+
+  AbstractItem& child = item.FindByID("not_exist_button");
+  ASSERT_EQ(child.GetType(), AbstractItem::NullObject);
+}
+
 TEST_F(ButtonItemTest, SerializeDeserializeGetTitle) {
   ButtonItem item("title");
   Bundle b = item.Serialize();
index 67fb14d..cbe87ef 100644 (file)
@@ -70,9 +70,19 @@ TEST_F(GroupItemTest, FindByID) {
   item.AddChild(std::make_shared<ButtonItem>("btn2", "test2"));
   ASSERT_EQ(item.GetChildren().size(), 2);
 
-  shared_ptr<AbstractItem> child = item.FindByID("btn2");
-  ButtonItem* btn = static_cast<ButtonItem*>(child.get());
-  ASSERT_EQ(btn->GetTitle(), "test2");
+  AbstractItem& child = item.FindByID("btn2");
+  ButtonItem& btn = static_cast<ButtonItem&>(child);
+  ASSERT_EQ(btn.GetTitle(), "test2");
+}
+
+TEST_F(GroupItemTest, FindByIDNullItemReturn) {
+  GroupItem item("GROUP1");
+  item.AddChild(std::make_shared<ButtonItem>("btn1", "test1"));
+  item.AddChild(std::make_shared<ButtonItem>("btn2", "test2"));
+  ASSERT_EQ(item.GetChildren().size(), 2);
+
+  AbstractItem& child = item.FindByID("not_exist_button");
+  ASSERT_EQ(child.GetType(), AbstractItem::NullObject);
 }
 
 int __fake_app_get_name(char** app_name) {