1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "common/resource_manager.h"
14 #include "common/logger.h"
15 #include "common/file_utils.h"
16 #include "common/string_utils.h"
17 #include "common/app_control.h"
18 #include "common/application_data.h"
19 #include "common/locale_manager.h"
21 using wgt::parse::AppControlInfo;
27 typedef std::vector<AppControlInfo> AppControlList;
30 const char* kSchemeTypeApp = "app://";
31 const char* kSchemeTypeFile = "file://";
32 // TODO(wy80.choi): comment out below unused const variables if needed.
33 // const char* kSchemeTypeHttp = "http://";
34 // const char* kSchemeTypeHttps = "https://";
35 // const char* kSchemeTypeWidget = "widget://";
37 // Default Start Files
38 const char* kDefaultStartFiles[] = {
46 static std::string GetMimeFromUri(const std::string& uri) {
47 // checking passed uri is local file
48 std::string file_uri_case(kSchemeTypeFile);
49 int ret = AUL_R_EINVAL;
50 char mimetype[128] = {0, };
51 size_t pos = std::string::npos;
52 if (utils::StartsWith(uri, file_uri_case)) {
53 // case 1. uri = file:///xxxx
54 ret = aul_get_mime_from_file(uri.substr(pos+file_uri_case.length()).c_str(),
55 mimetype, sizeof(mimetype));
56 } else if (utils::StartsWith(uri, "/")) {
57 // case 2. uri = /xxxx
58 ret = aul_get_mime_from_file(uri.c_str(),
59 mimetype, sizeof(mimetype));
62 if (ret == AUL_R_OK) {
63 return std::string(mimetype);
69 static bool CompareStringWithWildcard(const std::string& origin,
70 const std::string& target) {
71 std::string wildcard_str = utils::ReplaceAll(origin, "*", ".*");
73 std::regex re(wildcard_str, std::regex_constants::icase);
74 return std::regex_match(target.begin(), target.end(), re);
75 } catch (std::regex_error& e) {
76 LOGGER(ERROR) << "regex_error caught: " << e.what();
81 static bool CompareMime(const std::string& origin, const std::string& target) {
82 return CompareStringWithWildcard(origin, target);
85 static bool CompareUri(const std::string& origin_uri,
86 const std::string& target_uri) {
87 std::string origin_scheme = utils::SchemeName(origin_uri);
88 std::string target_scheme = utils::SchemeName(target_uri);
90 if (!origin_scheme.empty() && !target_scheme.empty()) {
91 return (origin_scheme == target_scheme);
93 return CompareStringWithWildcard(origin_uri, target_uri);
97 static AppControlList::const_iterator CompareMimeAndUri(
98 const AppControlList& operation_list,
99 const std::string& mime, const std::string& uri) {
100 if (mime.empty() && uri.empty()) {
101 // 1. request_mime = "", request_uri = ""
102 for (auto iter = operation_list.begin();
103 iter != operation_list.end(); ++iter) {
104 if (iter->mime().empty() && iter->uri().empty()) {
108 } else if (mime.empty() && !uri.empty()) {
109 // 2.. request_mime = "", request_uri = "blahblah"
110 for (auto iter = operation_list.begin();
111 iter != operation_list.end(); ++iter) {
112 if (iter->mime().empty() && CompareUri(iter->uri(), uri)) {
116 } else if (!mime.empty() && uri.empty()) {
117 // 3... request_mime = "blahblah", request_uri = ""
118 for (auto iter = operation_list.begin();
119 iter != operation_list.end(); ++iter) {
120 if (iter->uri().empty() && CompareMime(iter->mime(), mime)) {
125 // 4... request_mime = "blahblah", request_uri = "blahblah"
126 for (auto iter = operation_list.begin();
127 iter != operation_list.end(); ++iter) {
128 if (CompareMime(iter->mime(), mime) &&
129 CompareUri(iter->uri(), uri)) {
134 return operation_list.end();
137 static void FindOperations(AppControlList* app_control_list,
138 const std::string& operation) {
139 auto iter = app_control_list->begin();
140 while (iter != app_control_list->end()) {
141 if (iter->operation() != operation) {
142 app_control_list->erase(iter++);
149 static std::string InsertPrefixPath(const std::string& start_uri) {
150 if (start_uri.find("://") != std::string::npos) {
153 return std::string() + kSchemeTypeFile + "/" + start_uri;
159 ResourceManager::Resource::Resource(const std::string& uri)
160 : uri_(uri), should_reset_(true) {}
162 ResourceManager::Resource::Resource(const std::string& uri,
163 const std::string& mime)
164 : uri_(uri), mime_(mime), should_reset_(true) {}
166 ResourceManager::Resource::Resource(const std::string& uri,
167 const std::string& mime, bool should_reset)
168 : uri_(uri), mime_(mime), should_reset_(should_reset) {}
170 ResourceManager::Resource::Resource(const ResourceManager::Resource& res) {
174 ResourceManager::Resource& ResourceManager::Resource::operator=(
175 const ResourceManager::Resource& res) {
176 this->uri_ = res.uri();
177 this->mime_ = res.mime();
178 this->should_reset_ = res.should_reset();
182 bool ResourceManager::Resource::operator==(const Resource& res) {
183 if (this->uri_ == res.uri() && this->mime_ == res.mime()
184 && this->should_reset_ == res.should_reset()) {
191 ResourceManager::ResourceManager(ApplicationData* application_data,
192 LocaleManager* locale_manager)
193 : application_data_(application_data), locale_manager_(locale_manager) {
194 if (application_data != NULL) {
195 appid_ = application_data->tizen_application_info()->id();
199 std::string ResourceManager::GetDefaultOrEmpty() {
200 std::string default_src;
203 auto content_info = application_data_->content_info();
205 default_src = content_info->src();
207 LOGGER(WARN) << "ContentInfo is NULL.";
210 if (!default_src.empty()) {
211 return InsertPrefixPath(default_src);
214 // if there is no content src, find reserved index files
215 for (auto& start_file : kDefaultStartFiles) {
216 if (utils::Exists(resource_base_path_ + start_file)) {
217 default_src = start_file;
221 return InsertPrefixPath(default_src);
224 std::string ResourceManager::GetMatchedSrcOrUri(
225 const AppControlInfo& app_control_info) {
226 if (!app_control_info.src().empty()) {
227 return InsertPrefixPath(app_control_info.src());
230 if (!app_control_info.uri().empty()) {
231 return InsertPrefixPath(app_control_info.uri());
234 return GetDefaultOrEmpty();
237 std::unique_ptr<ResourceManager::Resource> ResourceManager::GetStartResource(
238 const AppControl* app_control) {
239 std::string operation = app_control->operation();
240 if (operation.empty()) {
241 LOGGER(ERROR) << "operation(mandatory) is NULL";
242 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
245 std::string mime = app_control->mime();
246 std::string uri = app_control->uri();
247 if (mime.empty() && !uri.empty()) {
248 mime = GetMimeFromUri(uri);
251 LOGGER(DEBUG) << "Passed AppControl data";
252 LOGGER(DEBUG) << " - operation : " << operation;
253 LOGGER(DEBUG) << " - mimetype : " << mime;
254 LOGGER(DEBUG) << " - uri : " << uri;
256 if (application_data_ == NULL ||
257 application_data_->app_control_info_list() == NULL) {
258 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
261 AppControlList app_control_list =
262 application_data_->app_control_info_list()->controls;
263 FindOperations(&app_control_list, operation);
265 if (!app_control_list.empty()) {
266 AppControlList::const_iterator iter =
267 CompareMimeAndUri(app_control_list, mime, uri);
268 if (iter != app_control_list.end()) {
269 // TODO(jh5.cho) : following comment will be added after SRPOL implement
270 return std::unique_ptr<Resource>(
271 new Resource(GetMatchedSrcOrUri(*iter), iter->mime()
272 /*, iter->should_reset()*/));
274 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
277 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
281 std::string ResourceManager::GetLocalizedPath(const std::string& origin) {
282 std::string file_scheme = std::string() + kSchemeTypeFile + "/";
283 std::string app_scheme = std::string() + kSchemeTypeApp;
284 std::string locale_path = "locales/";
285 auto find = locale_cache_.find(origin);
286 if (find != locale_cache_.end()) {
289 std::string& result = locale_cache_[origin];
290 std::string url = origin;
293 size_t pos = url.find_first_of("#?");
294 if (pos != std::string::npos) {
295 suffix = url.substr(pos);
299 if (utils::StartsWith(url, app_scheme)) {
301 url.erase(0, app_scheme.length());
304 std::string check = appid_ + "/";
305 if (utils::StartsWith(url, check)) {
306 url.erase(0, check.length());
308 LOGGER(ERROR) << "Invalid appid";
311 } else if (utils::StartsWith(url, file_scheme)) {
313 url.erase(0, file_scheme.length());
316 if (!url.empty() && url[url.length()-1] == '/') {
317 url.erase(url.length()-1, 1);
321 LOGGER(ERROR) << "URL Localization error";
325 for (auto& locales : locale_manager_->system_locales()) {
327 std::string app_locale_path = resource_base_path_ + locale_path;
328 if (!Exists(app_locale_path)) {
331 std::string resource_path = app_locale_path + locales + "/" + url;
332 if (Exists(resource_path)) {
333 result = "file://" + resource_path + suffix;
338 std::string default_locale = resource_base_path_ + url;
339 if (Exists(default_locale)) {
340 result = "file://" + default_locale + suffix;
343 result = url + suffix;
347 void ResourceManager::set_base_resource_path(const std::string& path) {
352 resource_base_path_ = path;
353 if (resource_base_path_[resource_base_path_.length()-1] != '/') {
354 resource_base_path_ += "/";
358 bool ResourceManager::Exists(const std::string& path) {
359 auto find = file_existed_cache_.find(path);
360 if (find != file_existed_cache_.end()) {
363 bool ret = file_existed_cache_[path] = utils::Exists(path);