2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "common/resource_manager.h"
26 #include "common/logger.h"
27 #include "common/file_utils.h"
28 #include "common/string_utils.h"
29 #include "common/app_control.h"
30 #include "common/application_data.h"
31 #include "common/locale_manager.h"
33 using wgt::parse::AppControlInfo;
39 typedef std::vector<AppControlInfo> AppControlList;
42 const char* kSchemeTypeApp = "app://";
43 const char* kSchemeTypeFile = "file://";
44 // TODO(wy80.choi): comment out below unused const variables if needed.
45 // const char* kSchemeTypeHttp = "http://";
46 // const char* kSchemeTypeHttps = "https://";
47 // const char* kSchemeTypeWidget = "widget://";
49 // Default Start Files
50 const char* kDefaultStartFiles[] = {
58 static std::string GetMimeFromUri(const std::string& uri) {
59 // checking passed uri is local file
60 std::string file_uri_case(kSchemeTypeFile);
61 int ret = AUL_R_EINVAL;
62 char mimetype[128] = {0, };
63 size_t pos = std::string::npos;
64 if (utils::StartsWith(uri, file_uri_case)) {
65 // case 1. uri = file:///xxxx
66 ret = aul_get_mime_from_file(uri.substr(pos+file_uri_case.length()).c_str(),
67 mimetype, sizeof(mimetype));
68 } else if (utils::StartsWith(uri, "/")) {
69 // case 2. uri = /xxxx
70 ret = aul_get_mime_from_file(uri.c_str(),
71 mimetype, sizeof(mimetype));
74 if (ret == AUL_R_OK) {
75 return std::string(mimetype);
81 static bool CompareStringWithWildcard(const std::string& origin,
82 const std::string& target) {
83 std::string wildcard_str = utils::ReplaceAll(origin, "*", ".*");
85 std::regex re(wildcard_str, std::regex_constants::icase);
86 return std::regex_match(target.begin(), target.end(), re);
87 } catch (std::regex_error& e) {
88 LOGGER(ERROR) << "regex_error caught: " << e.what();
93 static bool CompareMime(const std::string& origin, const std::string& target) {
94 return CompareStringWithWildcard(origin, target);
97 static bool CompareUri(const std::string& origin_uri,
98 const std::string& target_uri) {
99 std::string origin_scheme = utils::SchemeName(origin_uri);
100 std::string target_scheme = utils::SchemeName(target_uri);
102 if (!origin_scheme.empty() && !target_scheme.empty()) {
103 return (origin_scheme == target_scheme);
105 return CompareStringWithWildcard(origin_uri, target_uri);
109 static AppControlList::const_iterator CompareMimeAndUri(
110 const AppControlList& operation_list,
111 const std::string& mime, const std::string& uri) {
112 if (mime.empty() && uri.empty()) {
113 // 1. request_mime = "", request_uri = ""
114 for (auto iter = operation_list.begin();
115 iter != operation_list.end(); ++iter) {
116 if (iter->mime().empty() && iter->uri().empty()) {
120 } else if (mime.empty() && !uri.empty()) {
121 // 2.. request_mime = "", request_uri = "blahblah"
122 for (auto iter = operation_list.begin();
123 iter != operation_list.end(); ++iter) {
124 if (iter->mime().empty() && CompareUri(iter->uri(), uri)) {
128 } else if (!mime.empty() && uri.empty()) {
129 // 3... request_mime = "blahblah", request_uri = ""
130 for (auto iter = operation_list.begin();
131 iter != operation_list.end(); ++iter) {
132 if (iter->uri().empty() && CompareMime(iter->mime(), mime)) {
137 // 4... request_mime = "blahblah", request_uri = "blahblah"
138 for (auto iter = operation_list.begin();
139 iter != operation_list.end(); ++iter) {
140 if (CompareMime(iter->mime(), mime) &&
141 CompareUri(iter->uri(), uri)) {
146 return operation_list.end();
149 static void FindOperations(AppControlList* app_control_list,
150 const std::string& operation) {
151 auto iter = app_control_list->begin();
152 while (iter != app_control_list->end()) {
153 if (iter->operation() != operation) {
154 app_control_list->erase(iter++);
161 static std::string InsertPrefixPath(const std::string& start_uri) {
162 if (start_uri.find("://") != std::string::npos) {
165 return std::string() + kSchemeTypeFile + "/" + start_uri;
171 ResourceManager::Resource::Resource(const std::string& uri)
172 : uri_(uri), should_reset_(true) {}
174 ResourceManager::Resource::Resource(const std::string& uri,
175 const std::string& mime)
176 : uri_(uri), mime_(mime), should_reset_(true) {}
178 ResourceManager::Resource::Resource(const std::string& uri,
179 const std::string& mime, bool should_reset)
180 : uri_(uri), mime_(mime), should_reset_(should_reset) {}
182 ResourceManager::Resource::Resource(const ResourceManager::Resource& res) {
186 ResourceManager::Resource& ResourceManager::Resource::operator=(
187 const ResourceManager::Resource& res) {
188 this->uri_ = res.uri();
189 this->mime_ = res.mime();
190 this->should_reset_ = res.should_reset();
194 bool ResourceManager::Resource::operator==(const Resource& res) {
195 if (this->uri_ == res.uri() && this->mime_ == res.mime()
196 && this->should_reset_ == res.should_reset()) {
203 ResourceManager::ResourceManager(ApplicationData* application_data,
204 LocaleManager* locale_manager)
205 : application_data_(application_data), locale_manager_(locale_manager) {
206 if (application_data != NULL) {
207 appid_ = application_data->tizen_application_info()->id();
211 std::string ResourceManager::GetDefaultOrEmpty() {
212 std::string default_src;
215 auto content_info = application_data_->content_info();
217 default_src = content_info->src();
219 LOGGER(WARN) << "ContentInfo is NULL.";
222 if (!default_src.empty()) {
223 return InsertPrefixPath(default_src);
226 // if there is no content src, find reserved index files
227 for (auto& start_file : kDefaultStartFiles) {
228 if (utils::Exists(resource_base_path_ + start_file)) {
229 default_src = start_file;
233 return InsertPrefixPath(default_src);
236 std::string ResourceManager::GetMatchedSrcOrUri(
237 const AppControlInfo& app_control_info) {
238 if (!app_control_info.src().empty()) {
239 return InsertPrefixPath(app_control_info.src());
242 if (!app_control_info.uri().empty()) {
243 return InsertPrefixPath(app_control_info.uri());
246 return GetDefaultOrEmpty();
249 std::unique_ptr<ResourceManager::Resource> ResourceManager::GetStartResource(
250 const AppControl* app_control) {
251 std::string operation = app_control->operation();
252 if (operation.empty()) {
253 LOGGER(ERROR) << "operation(mandatory) is NULL";
254 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
257 std::string mime = app_control->mime();
258 std::string uri = app_control->uri();
259 if (mime.empty() && !uri.empty()) {
260 mime = GetMimeFromUri(uri);
263 LOGGER(DEBUG) << "Passed AppControl data";
264 LOGGER(DEBUG) << " - operation : " << operation;
265 LOGGER(DEBUG) << " - mimetype : " << mime;
266 LOGGER(DEBUG) << " - uri : " << uri;
268 if (application_data_ == NULL ||
269 application_data_->app_control_info_list() == NULL) {
270 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
273 AppControlList app_control_list =
274 application_data_->app_control_info_list()->controls;
275 FindOperations(&app_control_list, operation);
277 if (!app_control_list.empty()) {
278 AppControlList::const_iterator iter =
279 CompareMimeAndUri(app_control_list, mime, uri);
280 if (iter != app_control_list.end()) {
281 // TODO(jh5.cho) : following comment will be added after SRPOL implement
282 return std::unique_ptr<Resource>(
283 new Resource(GetMatchedSrcOrUri(*iter), iter->mime()
284 /*, iter->should_reset()*/));
286 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
289 return std::unique_ptr<Resource>(new Resource(GetDefaultOrEmpty()));
293 std::string ResourceManager::GetLocalizedPath(const std::string& origin) {
294 std::string file_scheme = std::string() + kSchemeTypeFile + "/";
295 std::string app_scheme = std::string() + kSchemeTypeApp;
296 std::string locale_path = "locales/";
297 auto find = locale_cache_.find(origin);
298 if (find != locale_cache_.end()) {
301 std::string& result = locale_cache_[origin];
302 std::string url = origin;
305 size_t pos = url.find_first_of("#?");
306 if (pos != std::string::npos) {
307 suffix = url.substr(pos);
311 if (utils::StartsWith(url, app_scheme)) {
313 url.erase(0, app_scheme.length());
316 std::string check = appid_ + "/";
317 if (utils::StartsWith(url, check)) {
318 url.erase(0, check.length());
320 LOGGER(ERROR) << "Invalid appid";
323 } else if (utils::StartsWith(url, file_scheme)) {
325 url.erase(0, file_scheme.length());
328 if (!url.empty() && url[url.length()-1] == '/') {
329 url.erase(url.length()-1, 1);
333 LOGGER(ERROR) << "URL Localization error";
337 for (auto& locales : locale_manager_->system_locales()) {
339 std::string app_locale_path = resource_base_path_ + locale_path;
340 if (!Exists(app_locale_path)) {
343 std::string resource_path = app_locale_path + locales + "/" + url;
344 if (Exists(resource_path)) {
345 result = "file://" + resource_path + suffix;
350 std::string default_locale = resource_base_path_ + url;
351 if (Exists(default_locale)) {
352 result = "file://" + default_locale + suffix;
355 result = url + suffix;
359 void ResourceManager::set_base_resource_path(const std::string& path) {
364 resource_base_path_ = path;
365 if (resource_base_path_[resource_base_path_.length()-1] != '/') {
366 resource_base_path_ += "/";
370 bool ResourceManager::Exists(const std::string& path) {
371 auto find = file_existed_cache_.find(path);
372 if (find != file_existed_cache_.end()) {
375 bool ret = file_existed_cache_[path] = utils::Exists(path);