#include "theme_plugin/theme_parser.h"
-#include <json/json.h>
#include <sys/types.h>
#include <fstream>
#include <streambuf>
#include <string>
+#include <vector>
#include "theme/dbus/request_broker.h"
#include "theme/loader/theme_info.h"
namespace ttm {
namespace plugin {
+bool ThemeParser::ExtractArray(const Json::Value& node,
+ std::string parent_key, ThemeInfoBuilder* builder) {
+ Json::ValueType element_type = node.begin()->type();
+ std::vector<std::string> array_values;
+ int ind = 0;
+ for (auto it = node.begin(); it != node.end(); ++it) {
+ std::string key = parent_key + "/" + std::to_string(ind++);
+ if (it->type() != element_type) {
+ LOG(ERROR) << "Json array element's type should be same";
+ return false;
+ }
+
+ if (it->isObject()) {
+ if (!ExtractJson(*it, key, builder))
+ return false;
+ } else if (it->isArray()) {
+ if (!ExtractArray(*it, key, builder))
+ return false;
+ } else {
+ array_values.emplace_back(it->asString());
+ }
+ }
+
+ if (element_type == Json::ValueType::arrayValue ||
+ element_type == Json::ValueType::objectValue)
+ return true;
+
+ if (array_values.empty()) {
+ LOG(ERROR) << "Empty array is not allowed";
+ return false;
+ }
+
+ builder->PutStringArray(parent_key, array_values);
+ return true;
+}
+
+bool ThemeParser::ExtractElement(const Json::Value &node,
+ const std::string parent_key, ThemeInfoBuilder* builder) {
+ builder->PutString(parent_key, node.asString());
+ return true;
+}
+
+bool ThemeParser::ExtractJson(const Json::Value& node,
+ std::string parent_key, ThemeInfoBuilder* builder) {
+ bool ret = true;
+ for (auto it = node.begin(); it != node.end(); ++it) {
+ std::string key = parent_key.empty() ?
+ it.name() : parent_key + "/" + it.name();
+ if (it->isObject())
+ ret &= ExtractJson(*it, key, builder);
+ else if (it->isArray())
+ ret &= ExtractArray(*it, key, builder);
+ else
+ ret &= ExtractElement(*it, key, builder);
+ }
+ return ret;
+}
+
loader::ThemeInfo ThemeParser::Inflate(const std::string id,
const std::string pkgid, uid_t uid, bool is_default) {
Json::CharReaderBuilder rbuilder;
ifs.close();
return {};
}
-
- // FIXME: this parser should parse more theme information.
ThemeInfoBuilder builder(id);
builder.PutString("pkgid", pkgid).
PutString("uid", std::to_string(uid)).
- PutString("is_default", is_default ? "true" : "false").
- PutString("version", root["version"].asString()).
- PutString("tool_version", root["tool_version"].asString()).
- PutString("title", root["header"]["title"].asString()).
- PutString("description", root["header"]["description"].asString());
+ PutString("is_default", is_default ? "true" : "false");
+
+ if (!ExtractJson(root, "", &builder)) {
+ LOG(ERROR) << "Fail to extract json value";
+ return {};
+ }
return builder.Build();
}
#ifndef THEME_PLUGIN_THEME_PARSER_H_
#define THEME_PLUGIN_THEME_PARSER_H_
+#include <json/json.h>
#include <sys/types.h>
#include <memory>
#include <string>
#include "theme/loader/theme_info.h"
+#include "theme_plugin/theme_info_builder.h"
namespace ttm {
namespace plugin {
bool Commit(ThemeOperation operation, const loader::ThemeInfo& theme);
private:
+ bool ExtractArray(const Json::Value& node,
+ std::string parent_key, ThemeInfoBuilder* builder);
+ bool ExtractElement(const Json::Value &node,
+ const std::string parent_key, ThemeInfoBuilder* builder);
+ bool ExtractJson(const Json::Value& node,
+ std::string parent_key, ThemeInfoBuilder* builder);
+
std::string path_;
};
--- /dev/null
+{
+ "array" : [
+ "a",
+ 1
+ ]
+}
--- /dev/null
+{
+ "array" : [
+ ]
+}
--- /dev/null
+{
+ "invalid"
+}
--- /dev/null
+{
+ "1D_array" : ["1", "2", "3"],
+ "2D_array" : [
+ ["1", "2", "3"],
+ ["1", "2", "3"]
+ ],
+ "3D_array" : [
+ [
+ ["1", "2", "3"],
+ ["1", "2", "3"]
+ ],
+ [
+ ["1", "2", "3"],
+ ["1", "2", "3"]
+ ]
+
+ ]
+}
{
"version": "1.0.0",
"tool_version": "1.00.38.820793",
+ "title": "GOGO Theme",
+ "description": "Example for theme spec",
"header": {
- "title": "GOGO Theme",
- "description": "Example for theme spec",
"profile": "wearable",
"resolutions": [
"720x1280"
}
}
]
-}
\ No newline at end of file
+}
#include "theme/loader/theme_info.h"
#include "theme_plugin/theme_parser.h"
+#include <string>
+#include <vector>
+
class ThemeParserTest : public testing::Test {
public:
virtual ~ThemeParserTest() {}
EXPECT_EQ(info.GetToolVersion(), "1.00.38.820793");
EXPECT_EQ(info.GetTitle(), "GOGO Theme");
EXPECT_EQ(info.GetDescription(), "Example for theme spec");
+ EXPECT_EQ(info.GetString("header/profile"), "wearable");
+ EXPECT_EQ(info.GetString("themes/0/home/app_tray"), "tray.png");
+ EXPECT_EQ(info.GetString("themes/0/home/appicon/org.tizen.browser"),
+ "browser.png");
+ EXPECT_EQ(info.GetString("themes/0/home/appicon/org.tizen.calculator"),
+ "calculator.png");
+ EXPECT_EQ(info.GetString("themes/0/home/appicon/org.tizen.calendar"),
+ "calendar.png");
+ EXPECT_EQ(info.GetString("themes/0/home/appicon/org.tizen.clock"),
+ "clock.png");
+ EXPECT_EQ(info.GetString("themes/0/home/appicon/org.tizen.contact"),
+ "contact.png");
+ EXPECT_EQ(info.GetString("themes/0/home/size"), "30");
+ EXPECT_EQ(info.GetString("themes/0/home/wallpaper"), "home_wallpaper.png");
+ EXPECT_EQ(info.GetString("themes/0/keyboard/keypad_bg_color"), "#050a28");
+ EXPECT_EQ(info.GetString("themes/0/watchface/id"), "org.tizen.gogowatch");
+ EXPECT_EQ(info.GetString("themes/0/watchface/url"),
+ "https://www.download.gogowatch/get");
+ EXPECT_EQ(info.GetStringArray("themes/0/preview"),
+ std::vector<std::string>({"GOGO_Preview.png"}));
+}
+
+TEST_F(ThemeParserTest, MultidimensionalArray) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_multidimensional_array.json");
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ std::vector<std::string> array_value({"1", "2", "3"});
+ EXPECT_EQ(info.GetStringArray("1D_array"), array_value);
+ EXPECT_EQ(info.GetStringArray("2D_array/0"), array_value);
+ EXPECT_EQ(info.GetStringArray("2D_array/1"), array_value);
+ EXPECT_EQ(info.GetStringArray("3D_array/0/0"), array_value);
+ EXPECT_EQ(info.GetStringArray("3D_array/0/1"), array_value);
+ EXPECT_EQ(info.GetStringArray("3D_array/1/0"), array_value);
+ EXPECT_EQ(info.GetStringArray("3D_array/1/1"), array_value);
+}
+
+TEST_F(ThemeParserTest, InvalidJson) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_invalid_json.json");
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, DifferentArrayElementType) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_different_array_element_type.json");
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
+}
+
+TEST_F(ThemeParserTest, EmptyArray) {
+ ttm::plugin::ThemeParser parser(
+ "test_samples/test_empty_array.json");
+ auto info = parser.Inflate("testid", "testpkgid", 5001, false);
+ EXPECT_FALSE(info.IsValid());
}